Reputation: 8804
This question is a continuation of Can XPath return only nodes that have a child of X? .
I want to find all "pets" that have foo, where some pets have a namespace and other pets do not.
Is it possible to use XPath to select only the nodes that have a particular child elements? For example, from this XML I only want the elements in pets that have a child of 'bar'. So the resulting dataset would contain the lizard and pig elements.
<pets xmlns="urn:cat-org:v1">
<cat>
<foo>don't care about this</foo>
</cat>
<dog xmlns:v1="urn:cat-org:v1">
<v1:foo>not this one either</foo>
</dog>
<lizard>
<bar>lizard should be returned, because it has a child of bar</bar>
</lizard>
<pig xmlns:v55="urn:cat-org:v1">
<v55:bar>return pig, too</bar>
</pig>
</pets>
Any advice would rock.
Upvotes: 1
Views: 460
Reputation: 243449
For example, from this XML I only want the elements in pets that have a child of 'bar'.
Use:
/*/*[*[local-name() = 'bar']]
This selects all children of the top element that have at least one child with local name "bar"
(regardless of prefixes if such exist).
XSLT - based verification:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select="/*/*[*[local-name() = 'bar']]"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document (corrected to be made well-formed):
<pets xmlns="urn:cat-org:v1">
<cat>
<foo>don't care about this</foo>
</cat>
<dog xmlns:v1="urn:cat-org:v1">
<v1:foo>not this one either</v1:foo>
</dog>
<lizard>
<bar>lizard should be returned, because it has a child of bar</bar>
</lizard>
<pig xmlns:v55="urn:cat-org:v1">
<v55:bar>return pig, too</v55:bar>
</pig>
</pets>
the XPath expression is evaluated and the selected elements are copied to the output:
<lizard xmlns="urn:cat-org:v1">
<bar>lizard should be returned, because it has a child of bar</bar>
</lizard>
<pig xmlns="urn:cat-org:v1" xmlns:v55="urn:cat-org:v1">
<v55:bar>return pig, too</v55:bar>
</pig>
Upvotes: 3