Win a copy of Think Java: How to Think Like a Computer Scientist this week in the Java in General forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

XPath expression

 
Vasim Patel
Ranch Hand
Posts: 87
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am unable to understand an XPath expression. Somobody please help.

Here is an XML document:

<root>
<B>
<a>1</a>
<a>2</a>
<a>1</a>
<x>3</x>
<x>4</x>
</B>
<B>
<a>3</a>
<a>1</a>
<a>2</a>
<a>3</a>
<x>5</x>
<x>4</x>
</B>
</root>


I am trying to evaluate an XPath expression, "//a[preceding::a=.]"

To understand this expression, I am using XML Spy's Evaluate XPath feature. I break it into 3 parts

Part 1:
"//a" : This gives all the 'a' elements. It returns following elements

<B>
<a>1</a>
<a>2</a>
<a>1</a>
</B>
<B>
<a>3</a>
<a>1</a>
<a>2</a>
<a>3</a>
</B>

Part 2:
"//a[preceding::a]": This gives me all a's which have preceding 'a'. It returns following elements:

<B>
<a>2</a>
<a>1</a>
</B>
<B>
<a>3</a>
<a>1</a>
<a>2</a>
<a>3</a>
</B>

I understand till here:

Part 3:
Now for the expression
"//a[preceding::a=.]": This should give me all a's which have preceding a's as elements and whose value is equal to current selected value.

Lets say I am first 'a' element.
<root>
<B>
<a>1</a> -> I am selecting this
<a>2</a>
<a>1</a>
<x>3</x>
<x>4</x>
</B>
<B>
<a>3</a>
<a>1</a>
<a>2</a>
<a>3</a>
<x>5</x>
<x>4</x>
</B>
</root>



Shouldn't I get only 2 elements like this

<B>
<a>1</a>
</B>
<B>
<a>1</a>
</B>

But I am getting

<B>
<a>1</a>
</B>
<B>
<a>1</a>
<a>2</a>
<a>3</a>
</B>

Why am I getting all those element a's which have value 2 and 3.

Can anybody pls help

regards
Vasim
 
Nitish Bahadur
Ranch Hand
Posts: 118
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Vasim,

Try replacing the preceding with 'preceding-sibling' to get the desired result.

Regards,
Nitish.
 
Danilo Sato
Greenhorn
Posts: 4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Actually, when you use //a[preceding::a=.] you are looking for all <a> elements which have another preceding <a> element with the same value (by preceding I mean: happens before in the xml document). Here why you get those results:

<root>
<B>
<a>1</a> *
<a>2</a> #
<a>1</a> (*)
<x>3</x>
<x>4</x>
</B>
<B>
<a>3</a> $
<a>1</a> (*)
<a>2</a> (#)
<a>3</a> ($)
<x>5</x>
<x>4</x>
</B>
</root>

The matching nodes are included in () and their preceding a element is marked with the same symbol. If you used preceding-sibling you would get just ($) and the first (*).

Hope this helps,
Danilo
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic