Reputation: 850
Let's say I have the following xml:
<root>
<person>
<name>John</name>
</person>
<children>
<person>
<name>Jack</name>
</person>
</children>
</root>
Is it possible to select both persons at once? Assuming that I don't know that the other person is in the children tag, they could easily be in the spouse tag or something completely different and possibly in an other child. I do know all persons I need are in the root tag (not necessarily the document root).
Upvotes: 5
Views: 17243
Reputation: 107267
You can use
//person
or
//*[local-name()='person']
to find any person
elements in the document, but be careful - certain xsl processors (like Microsoft's), the performance of double slash can be poor on large xml
documents because all nodes in the document need to be evaluated.
Edit :
If you know there are only 2 paths to 'person' then you can avoid the //
altogether:
<xsl:for-each select="/root/person | /root/children/person">
<outputPerson>
<xsl:value-of select="name/text()" />
</outputPerson>
</xsl:for-each>
OR namespace agnostic:
<xsl:for-each select="/*[local-name()='root']/*[local-name()='person']
| /*[local-name()='root']/*[local-name()='children']/*[local-name()='person']">
Upvotes: 11
Reputation: 243449
In Petar Ivanov's answer the definition of //
is wrong.
Here is the correct definition from the XPath 1.0 W3C Specification:
//
is short for/descendant-or-self::node()/
Upvotes: 3
Reputation: 5164
As nonnb stated double slash's performance are poor on large xml documents.
So //name
would do the trick but might bring up much more elements that you expect.
Plus imagine within your root element you have some elements that are not persons that might have descendants element with the name name, according to your question you don't want to bring them up, //name
will bring them up.
You should affine your context-node at max so performance wise your XPath will be optimal.
For this precise document I would use
/root/descendant::person/name
Hope it helps,
Upvotes: 1
Reputation: 1973
Or you can use:
root//person
So you search for persion only in root element
Upvotes: 1
Reputation: 93030
//name
will match both, no matter where they are in the xml tree.
//
Selects nodes in the document from the current node that match the selection no matter where they are (link)
Upvotes: 1