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"?

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
dacracot
  • 22,002
  • 26
  • 104
  • 152
  • 1
    The XPath expression in the currently accepted answer 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 Nov 22 '08 at 20:57

4 Answers4

5

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
  • 3,660
  • 20
  • 11
2

I think this will work:

/root/base/tent[/root/bucket/tent/@key = @key ]/@color
Garth Gilmour
  • 11,124
  • 5
  • 25
  • 35
  • The xpath works for the given XML but is not a generic solution. If the XML is: ... snip ... then it will return all three colors. – Sixto Saez Sep 26 '08 at 21:48
  • 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 Nov 22 '08 at 20:56
1

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
  • 94,622
  • 24
  • 146
  • 218
0

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
  • 9,996
  • 7
  • 51
  • 82