xpath descendant question

C

CAFxX

Hi everybody, I have a problem with a xpath query.
Suppose you have something like this:

<a>
<b>X</b>
<a>
<c>
<b>Y</b>
</c>
</a>
</a>

Right now to obtain a list of <a> containg a certain token I do:

//a[ contains( descendant-or-self::*, 'token' ) ]

the problem is that, in the case above, searching for the token Y would
give both <a>s, whereas I need only the innermost one (i.e. the nearest
<a> ancestor of the fragment containing the searched token). How can I
translate this in xpath?
Thank you and best regards,
CAFxX
 
P

Peter Flynn

CAFxX said:
Hi everybody, I have a problem with a xpath query.
Suppose you have something like this:

<a>
<b>X</b>
<a>
<c>
<b>Y</b>
</c>
</a>
</a>

Right now to obtain a list of <a> containg a certain token I do:

//a[ contains( descendant-or-self::*, 'token' ) ]

the problem is that, in the case above, searching for the token Y would
give both <a>s, whereas I need only the innermost one (i.e. the nearest
<a> ancestor of the fragment containing the searched token). How can I
translate this in xpath?

//*[contains(.,'Y')]/ancestor::a[1]

///Peter
 
C

CAFxX

Ok, I suddenly realized what axes are all about. Thank you very much!

Peter Flynn ha scritto:
CAFxX said:
Hi everybody, I have a problem with a xpath query.
Suppose you have something like this:

<a>
<b>X</b>
<a>
<c>
<b>Y</b>
</c>
</a>
</a>

Right now to obtain a list of <a> containg a certain token I do:

//a[ contains( descendant-or-self::*, 'token' ) ]

the problem is that, in the case above, searching for the token Y
would give both <a>s, whereas I need only the innermost one (i.e. the
nearest <a> ancestor of the fragment containing the searched token).
How can I translate this in xpath?

//*[contains(.,'Y')]/ancestor::a[1]

///Peter
 
C

CAFxX

I found just a minor error in your code, it should be

//*[contains(child::text(),'Y')]/ancestor::a[1]

and not

//*[contains(.,'Y')]/ancestor::a[1]

right?

Peter Flynn ha scritto:
CAFxX said:
Hi everybody, I have a problem with a xpath query.
Suppose you have something like this:

<a>
<b>X</b>
<a>
<c>
<b>Y</b>
</c>
</a>
</a>

Right now to obtain a list of <a> containg a certain token I do:

//a[ contains( descendant-or-self::*, 'token' ) ]

the problem is that, in the case above, searching for the token Y
would give both <a>s, whereas I need only the innermost one (i.e. the
nearest <a> ancestor of the fragment containing the searched token).
How can I translate this in xpath?

//*[contains(.,'Y')]/ancestor::a[1]

///Peter
 
P

Peter Flynn

CAFxX said:
I found just a minor error in your code, it should be

//*[contains(child::text(),'Y')]/ancestor::a[1]

and not

//*[contains(.,'Y')]/ancestor::a[1]

right?

In some circumstances...it depends on what other markup is in your
real-life document. If you want to find all a elements which have a Y in
any element within them, regardless of how deep, then my example is
correct, because <a><b>Y</b></a> contains Y somewhere in it.But the same
is then true of your outer a as well, because
<a><b>X</b><a><c><b>Y</b></c></a></a> contains XY, which contains a Y.

If what you really want is the a ancestor of all b elements that
directly contain Y, then you need to specify that:

//b[contains(text(),'Y')]/ancestor::a[1]

This will return your nested a element rather than both a elements.

///Peter
--
XML FAQ: http://xml.silmaril.ie/

Peter Flynn ha scritto:
CAFxX said:
Hi everybody, I have a problem with a xpath query.
Suppose you have something like this:

<a>
<b>X</b>
<a>
<c>
<b>Y</b>
</c>
</a>
</a>

Right now to obtain a list of <a> containg a certain token I do:

//a[ contains( descendant-or-self::*, 'token' ) ]

the problem is that, in the case above, searching for the token Y
would give both <a>s, whereas I need only the innermost one (i.e. the
nearest <a> ancestor of the fragment containing the searched token).
How can I translate this in xpath?

//*[contains(.,'Y')]/ancestor::a[1]

///Peter
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,246
Members
46,841
Latest member
WilmerBelg

Latest Threads

Top