views:

48

answers:

2

Hi,

a sample of xml document:

  <xml>
    <list>
      <item refid="1" />
      <item refid="3" />
    </list>
    <catalogue>
      <model id="1"><details /></model>
      <model id="2"><details /></model>
      <model id="3"><details /></model>
    </catalogue>
  </xml>

I'd like to query something like //model[ @id = (//item/@refid) ] to obtain all "model" having a referenced id in "list"

+2  A: 

Your xpath expression should already return exactly what you want. Quoting from http://www.w3.org/TR/xpath/#booleans, 5th paragraph:

If one object to be compared is a node-set and the other is a string, then the comparison will be true if and only if there is a node in the node-set such that the result of performing the comparison on the string-value of the node and the other string is true

Jörn Horstmann
+2  A: 

I'd like to query something like //model[ @id = (//item/@refid) ] to obtain all "model" having a referenced id in "list"

The main problem here is your lack of confidence and not actually running an XPath engine to evaluate the expressions you've come up with.

If you evaluate the XPath expression you proposed:

//model[ @id = (//item/@refid) ]

You'll see that it selects exactly the (two) model elements, whose id attributes are referenced by the refid attributes of item elements that are children of list.

@Jörn-Horstmann in his answer already explained why you get these results.

A minor remark is to generally avoid using the // abbreviation. It causes the whole document to be scanned and is very inefficient. In this case I would use the equivalent but probably faster to evaluate XPath expression:

/*/catalogue/model[@id = /*/list/item/@refid]
Dimitre Novatchev
Thanks, your conclusion is exactly what I was looking for, evaluating an alternative xpath operation.
Steel Plume