tags:

views:

316

answers:

4

Say I have the following XML...

<root>
  <base>
    <tent key="1" color="red"/>
    <tent key="2" color="yellow"/>
    <tent key="3" color="blue"/>
  </base>
  <bucket>
    <tent key="1"/>
    <tent key="3"/>
  </bucket>
</root>

...what would the XPath be that returns that the "bucket" contains "red" and "blue"?

+2  A: 

I think this will work:

/root/base/tent[/root/bucket/tent/@key = @key ]/@color
Garth Gilmour
The xpath works for the given XML but is not a generic solution. If the XML is:<root>... snip ... <bucket> <tent key="1" /> <tent key="3" /> </bucket> <bucket> <tent key="2" /> </bucket></root>then it will return all three colors.
Sixto Saez
This XPath expression doesn't select any "bucket" nodes at all. It selects "color" attributes. So this answer is wrong. dacracot, please, accept Jeni's answer, which is a good one.
Dimitre Novatchev
+1  A: 

It's not pretty. As with any lookup, you need to use current():

/root/bucket[/root/base/tent[@key = current()/tent/@key]/@color = 'blue' or /root/base/tent[@key = current()/tent/@key]/@color = 'red']

Robert Rossney
+3  A: 

If you're using XSLT, I'd recommend setting up a key:

<xsl:key name="tents" match="base/tent" use="@key" />

You can then get the <tent> within <base> with a particular key using

key('tents', $id)

Then you can do

key('tents', /root/bucket/tent/@key)/@color

or, if $bucket is a particular <bucket> element,

key('tents', $bucket/tent/@key)/@color
JeniT
A: 

JeniT has the appropriate response / code listed here. You need to create the key before you walk the XML Document, then perform matches against that key.

David Robbins