Rainforest

Sankuru

Implementeren, customiseren, uitbreiden, en troubleshooten van Joomla/Virtuemart

Views: 807

Wij helpen met ...

Virtuemart
Joomfish
Andere extensies
SocialTwist Tell-a-Friend

Automatische vertaling

English Arabic Chinese (Simplified) German Japanese Russian Spanish



Hergebruik open source

Datgene wat U nodig hebt, bestaat vaak al, en dekt 80% van Uw behoeften. Wij zorgen voor de ontbrekende 20%.

Gratis offerte

Vraag vandaag nog gratis een offerte aan.

XPath, finding multi-class elements by CSS class PDF Afdrukken E-mail
Waardering: / 0
SlechtZeer goed 
Geschreven door erik   
dinsdag 01 december 2009 07:12
There are no translations available.

 

When we try to find all elements with css class 'foo', the following XPath expression:

//div[@class='foo']


will not match the following example:

<div class='foo bar'>

 

The XPath expression above will not return multi-class elements. You will find the solution discussed, for the problem here and here. I have replaced spaces by dashes ("-"), in order to get a better grip on things.

 

The XPath expression that solves the issue is:


//div[contains(concat('-',@class,'-'),'-foo-')]

 

Why exactly does this expression work?

 

Let's look at the definitions for the functions contains() and concat():

 

contains(string1,string2) Returns true if string1 contains string2, otherwise it returns false.
concat(string,string,...) Returns the concatenation of the strings.

 

We try a few examples for the XPath expression:

 

other contains("-other-","-foo-") false
-other- contains("--other--","-foo-") false
foo contains("-foo-","-foo-") true
foo- contains("-foo--","-foo-") true
-foo contains("--foo-","-foo-") true
-foo- contains("--foo--","-foo-") true
foo-bar contains("-foo-bar-","-foo-") true
bar-foo contains("-bar-foo-","-foo-") true
bar-foo-other contains("-bar-foo-other-","-foo-") true

 

It seems to work for all the examples above.

 

But then again, how do we know that it will work for all possible examples? The general cases for which it has to work, are:

 

Case Example General regular expression
the value is at the beginning of the space-separated list, optionally preceded by spaces
foo-bar -*foo-+.*
the value is at the end of the space-separated list, optionally followed by spaces
bar-foo .*-+foo-*
the value is in the middle of the space-separated list
bar-foo-other .*-+foo-+.*

 

In order to prove that the XPath expression is correct, we need to prove that the following expressions are true:

 

beginning contains("--*foo-+.*-","-foo-")
end contains("-.*-+foo-*-","-foo-")
middle contains("-.*-+foo-+.*-","-foo-")

 

From the definition of the function contains(), we can derive the rule:

 

x contains y when x = .*y.*

 

We must demonstrate that the matches for regular expressions on the left are fully-contained subsets of the matches for the regular expression on the right:

 

left right
beginning --*foo-+.*- .*-foo-.*
end -.*-+foo-*-
middle -.*-+foo-+.*-

 

Therefore, we must demonstrate that the prefixes are a subset of the right-left prefix and the right suffixes are a subset of the right prefix for the regular expression on the right:

 

prefix suffix
left right left right
beginning --* .*- -+.*- -.*
end -.*-+ -*-
middle -.*-+ -+.*-

 

We represent the subset operator as <=. Any regular expression E is always a subset of the Any expression, that is, .* :

 

E <= .*

 

Now, we can construct the proof:

 

left right
beginning --* <= .*-
-*- <
= .*-
-* <
= .*
-+.*- <= -.*
+.*- <
= .*
end -.*-+ <= .*-
-.*-*- <
= .*-
-.*-* <
= .*
-*- <= -.*
*- <
= .*
middle (same as end) (same as beginning)

 


Therefore, the XPath expression for finding multi-class elements by CSS class is correct.

 

I guess that this is probably my favourite mathematical proof up till now. I wonder if anybody else concocted this stuff before (I suspect someone must have...), because then I should to credit that person for coming up with such very ugly table, before I did. I really had to share this with you guys :-)

 


blog comments powered by Disqus
 
 
Joomla 1.5 Templates by Joomlashack