Complicated XPATH to return a nodeset based on a sibling node's value

B

Brad

Help, I have a really complicated XPATH request I can't wrap my head around

I have an XML nodeset like this:

<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value1</a2>
</a>
<a>
<a1 attr="key">DontUse</a1>
<a1 attr="val">Value2</a1>
</a>
<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value3</a1>
</a>

How do I form an XPATH that will return me the nodeset a/a1[@attr="Val"]
only when a/a1[@attr="key"] is equal to "Use"??? IE, I want a nodeset with
["Value1", "Value3"]

Thanks for any insight! This is driving me nuts! :-(
 
A

A. Bolmarcich

Help, I have a really complicated XPATH request I can't wrap my head around

I have an XML nodeset like this:

<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value1</a2>
</a>
<a>
<a1 attr="key">DontUse</a1>
<a1 attr="val">Value2</a1>
</a>
<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value3</a1>
</a>

How do I form an XPATH that will return me the nodeset a/a1[@attr="Val"]
only when a/a1[@attr="key"] is equal to "Use"??? IE, I want a nodeset with
["Value1", "Value3"]

Thanks for any insight! This is driving me nuts! :-(

One way is to work from the root of the tree structure inward:

- You want the a1 nodes with the right attribute and text values

a/a1[@attr="key" and .="Use"]

- Within those nodes you want the a1 nodes of the same parent

a/a1[@attr="key" and .="Use"]/../a1

with the right attribute value

a/a1[@attr="key" and .="Use"]/../a1[@attr="val"]

- Within those nodes you (maybe) want only the text.

a/a1[@attr="key" and .="Use"]/../a1[@attr="val"]/text()
 
P

Patrick TJ McPhee

% How do I form an XPATH that will return me the nodeset a/a1[@attr="Val"]
% only when a/a1[@attr="key"] is equal to "Use"??? IE, I want a nodeset with
% ["Value1", "Value3"]


First pick a

a[a1/@attr = "key" and a1 = "Use"]

then get the correct a1 from that

a[a1/@attr = "key" and a1 = "Use"]/a1[@attr = "val"]
 
P

Patrick TJ McPhee

% a[a1/@attr = "key" and a1 = "Use"]/a1[@attr = "val"]

There's a subtle error here. It should be

a[a1[@attr = "key" and . = "Use"]]/a1[@attr = "val"]

You could read this as `the set of a1 elements with attribute attr equal
to "val", whose parent element is an a element which has a child a1
element, which has attribute attr equal to "key" and whose text content
is "Use"'.

The incorrect version might read `the set of a1 elements with attribute
attr equal to "val", whose parent element is an a element which has a
child a1 element which has attribute attr equal to "key" and which also
has a child a1 element whose text content is "Use"'.

Sorry.
 
T

tahire72

Help, I have a really complicated XPATH request I can't wrap my head around

I have an XML nodeset like this:

<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value1</a2>
</a>
<a>
<a1 attr="key">DontUse</a1>
<a1 attr="val">Value2</a1>
</a>
<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value3</a1>
</a>

How do I form an XPATH that will return me the nodeset a/a1[@attr="Val"]
only when a/a1[@attr="key"] is equal to "Use"??? IE, I want a nodeset with
["Value1", "Value3"]

Thanks for any insight! This is driving me nuts! :-(

Detailed XPath tutorial here; http://www.liquid-technologies.com/xpath-tutorial.aspx
 
J

Joe Kesselman

Help, I have a really complicated XPATH request I can't wrap my head around

I have an XML nodeset like this:

<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value1</a2>
</a>
<a>
<a1 attr="key">DontUse</a1>
<a1 attr="val">Value2</a1>
</a>
<a>
<a1 attr="key">Use</a1>
<a1 attr="val">Value3</a1>
</a>

How do I form an XPATH that will return me the nodeset a/a1[@attr="Val"]
only when a/a1[@attr="key"] is equal to "Use"??? IE, I want a nodeset with
["Value1", "Value3"]

Assuming you meant "val", not "Val"... Try expressing it in simplest
English form. "Find the a's whose key is 'Use' and return their val
elements."

a[a1[@attr="key"]="Use"]/a1[@attr="Val"]


Note that this is a perfect example of why documents that use attributes
to name the values are a Bad Practice. Your document should almost
certainly have been something more like:

<entry>
<key>Use</key>
<val>Value1</key>
</entry>

which would simplify your XPath to
entry[key="use"]/val

Much easier to maintain, and in many implementations will run
significantly faster.


--
Joe Kesselman,
http://www.love-song-productions.com/people/keshlam/index.html

{} ASCII Ribbon Campaign | "may'ron DaroQbe'chugh vaj bIrIQbej" --
/\ Stamp out HTML mail! | "Put down the squeezebox & nobody gets hurt."
 

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,828
Messages
2,569,736
Members
45,520
Latest member
JudithMorf

Latest Threads

Top