Reputation: 131
In the past I have removed empty tags using a separate transform as shown below, but now I must do it within the same XSLT 2.0 transform.
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="*[not(node()) and not(./@*)]"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Given this XML, I want to remove all empty tags from the policy node. The XML is can be up to 40 MB or so:
<?xml version="1.0" encoding="UTF-8"?>
<myroot>
<data>
<data1>abc</data1>
<data2>123</data2>
</data>
<policy>
<policydata1>Hello World!</policydata1>
<policydata2/>
</policy>
</myroot>
My thought is using XSLT 2.0 I can retain the output of the transform that pertains to the policy node in a variable defined as an 'element' so I can treat it like XML and then iterate over the variable to remove the empty tags:
<xsl:variable name="completepolicy" as="element()">
<policy>
<policydata1>Hello World!</policydata1>
<policydata2/>
</policy>
</xsl:variable>
The answer of how to incorporate the tag removal within the variable without affecting the rest of the templates in my transform seems to be escaping me. Can you help me with what is probably obvious?
NOTE the reason I am proposing a variable around the 'policy' output is that I already have it declared due to a need to extract some messages from the transform for output elsewhere.
Upvotes: 1
Views: 799
Reputation: 163262
It's not clear to me why you can't simply incorporate the rule
<xsl:template match="*[not(node()) and not(./@*)]"/>
in your existing stylesheet, perhaps with increased priority. I guess it depends on what other template rules are doing. If you need the empty nodes to be present in the tree that is bound to $completepolicy and then want to remove them in the second phase of processing, I would do that using modes: one mode for template rules applying to each phase of processing.
Upvotes: 0
Reputation: 243459
Just use your original transformation, but replace:
<xsl:template match="*[not(node()) and not(./@*)]"/>
with:
<xsl:template match="policy/*[not(node()) and not(@*)]"/>
Upvotes: 1