How to write a xpath to match all elements except a particular element
Solution 1
I want to write a template that matches all nodes except ServiceNode i.e. NodeA to NodeX.
If by "node" you mean element, then use:
<xsl:template match="*[not(self::ServiceNode)]">
If by "node" you mean any node (of type element, text, comment, processing-instruction): use
<xsl:template match="node()[not(self::ServiceNode)]">
If you want only children of Document
to be matched use:
<xsl:template match="Document/node()[not(self::ServiceNode)]">
If you want only children of the top element to be matched use:
<xsl:template match="/*/node()[not(self::ServiceNode)]">
Solution 2
You should better use this expression:
*[not(self::ServiceNode)]
As incorporated in an XSLT:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/*">
<xsl:apply-templates select="*[not(self::ServiceNode)]"/>
</xsl:template>
<xsl:template match="*">
<xsl:value-of select="."/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
With this XML sample:
<Document>
<NodeA>1</NodeA>
<NodeB>2</NodeB>
<ServiceNode>3</ServiceNode>
<NodeX>4</NodeX>
</Document>
It will give a correct result:
1
2
4
Solution 3
<xsl:template match="Document/*[name() != 'ServiceNode']">
(or local-name()
if you have to deal with namespaces)
Solution 4
You could use two templates:
<xsl:template match="Document/*">
...do something...
</xsl:template>
<xsl:template match="Document/ServiceNode" />
The later template will take priority, so the first template will match everything except ServiceNode.
Unmesh Kondolikar
Updated on January 06, 2020Comments
-
Unmesh Kondolikar over 4 years
I am writing an XSL transformation. I want to write a template which matches all the child elements of the document except one particular node. My xml looks like this -
<Document> <NodeA></NodeA> <NodeB></NodeB> <ServiceNode></ServiceNode> <NodeX></NodeX> </Document>
I want to write a template that matches all nodes except
ServiceNode
i.e.NodeA
toNodeX
. How to write this Xpath to get -<xsl:template match="ALL Nodex Except ServiceNode">
-
Chris Dolan over 13 yearsI recommend testing in a live evaluator like whitebeam.org/library/guide/TechNotes/xpathtestbed.rhtm where you can paste expressions like //*[name()!="pet"]
-
Michael Kay over 13 yearsCorrect. This is better than testing on name() or local-name(). In XPath 2.0 an alternative is (* except ServiceNode)
-
Admin over 13 yearsI agree. Better than
name()
. -
Admin over 13 yearsThis could be useful in some cases, besides it doesn't answer this question properly.