Reputation: 5040
I have an xml file like:
<work>
<job name="dummy">
<task>template</task>
<user>template</user>
</job>
<job name="unit1">
<task>abc</task>
<user>def</user>
</job>
<job name="unit2">
<task>abc1</task>
<user>xyz</user>
</job>
</work>
I want to remove all the elements except the first job whose name is not "dummy". Some files may or may not contain jobs with name "dummy". So in the end the tranformed file should look like,
<work>
<job name="unit1">
<task>abc</task>
<user>def</user>
</job>
</work>
How do I filter and select in xslt?
Upvotes: 0
Views: 889
Reputation: 167471
You can use
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="job[@name = 'dummy'] | job[not(@name = 'dummy')][position() > 1]"/>
Upvotes: 2
Reputation: 122364
The simplest approach would be
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:template match="/*">
<xsl:copy>
<!-- copy the first job-whose-name-is-not-dummy -->
<xsl:copy-of select="job[not(@name = 'dummy')][1]" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
An alternative way to think about it if this is part of a larger transformation would be to think about what you want to ignore rather than what you want to keep:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- copy everything as-is unless overridden -->
<xsl:template match="@*|node()">
<xsl:copy><xsl:apply-templates select="@*|node()" /></xsl:copy>
</xsl:template>
<!-- ignore jobs named dummy -->
<xsl:template match="job[@name = 'dummy']" />
<!-- ignore jobs *not* named dummy, apart from the first one -->
<xsl:template match="job[not(@name = 'dummy')][position() > 1]" />
</xsl:stylesheet>
That way you can define further templates if you want to do something other than straight copying with the job
element that you do want to keep.
Upvotes: 3