Reputation: 45
For example I have an XML sample like this
<a>
<a1>A1</a1>
<a11>A11</a11>
<a2>A2</a2>
Text <strong>text</strong> text...
<a>
How can I use XPath to select node a
contain only
<a>
<a2>A2</a2>
Text <strong>text</strong> text...
<a>
Upvotes: 1
Views: 1457
Reputation: 52848
This xpath:
//a[normalize-space(.)='A2 Text text text...']
Would only select:
<a>
<a2>A2</a2>
Text <strong>text</strong> text...
</a>
XSLT Example...
XML Input
<doc>
<a>
<a1>A1</a1>
<a11>A11</a11>
<a2>A2</a2>
Text <strong>text</strong> text...
</a>
<a>
<a2>A2</a2>
Text <strong>text</strong> text...
</a>
</doc>
XSLT 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select="//a[normalize-space(.)='A2 Text text text...']"/>
</xsl:template>
</xsl:stylesheet>
XML Output
<a>
<a2>A2</a2>
Text <strong>text</strong> text...
</a>
Upvotes: 0
Reputation: 243459
XPath is a query language for XML documents. This means that an XPath expression can only select a set of nodes and/or extract data.
Remember: An XPath expression can never cause modufication of the structure of an XML document (such as deleting a node).
The answer is that no XPath expression is going to select the node you want because there isn't such a node in the XML document.
What you want can easily be accomplished with XSLT and (not so easily) with XQuery:
<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="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[starts-with(name(), 'a1')]"/>
</xsl:stylesheet>
When this transformation is applied on the provided XML document:
<a>
<a1>A1</a1>
<a11>A11</a11>
<a2>A2</a2> Text
<strong>text</strong> text...
</a>
the wanted, correct result is produced:
<a>
<a2>A2</a2> Text
<strong>text</strong> text...
</a>
Upvotes: 1
Reputation: 4871
Not sure if this is flexible enough for you, but it should get you started
/a/a1 | a/text() | /a/*[not(starts-with(name(), 'a'))]
You can play around with it easily here: http://www.xpathtester.com/test
Upvotes: 1