Reputation: 822
Say I want to select all field
nodes from an xml document efficiently.
The document might look like this:
<pageSet>
<field>
<foo></foo>
<bar></bar>
</field>
<subform>
<field>
<foo></foo>
<bar></bar>
</field>
<subform>
<field>
<foo></foo>
<bar></bar>
</field>
<field/>
</subform>
</subform>
</pageSet>
A field
node can only have ancestors of type pageSet
or subform
.
Is there a way to get all field nodes in a way like this?
/(pageSet or subform nodes of unknown depth)/field
I want to tell the xpath-processor to stop looking deeper after it found an element other than subform
or pageSet
. Because those can have other very nested structures that slow the xpath evaluation.
Example:
/pageSet/subform/one_or_more_unknown_nodes/field
can not happen! When the xpath processor finds one_or_more_unknown_nodes
it should not look any deeper, as there will be no field
node.
Upvotes: 2
Views: 249
Reputation: 163625
Well, firstly, you can't tell the XPath processor where to look: it will make its own decisions. The best you can do is to give it enough information so it knows where it needs to look.
In theory, given the expression
//field[not(ancestor::*[not(self::pageSet or self::subform)])]
the XPath processor has enough information to know that it doesn't need to search the descendants of an element whose name isn't pageSet or subform.
But I doubt that your XPath processor is smart enough to do that.
And it might not even be a smart strategy anyway. Depending how the data is stored and what indexes are available, the fastest way of evaluating that query might be to find all the field
elements and then check their ancestry. (Which means that if the predicate is always true anyway, as you suggest, then you've actually slowed the query down by providing the predicate.)
The bottom line is that you can't sensibly discuss the performance of XPath expressions without knowing quite a lot about the internals of your particular XPath processor.
Upvotes: 2