Reputation: 728
Using XSLT, how can I comment a single node without commenting its children?
I have this html:
<html>
<body>
<div class="blah" style="blahblah">
<span>
<p>test</p>
</span>
</div>
</body>
</html>
I would like this output:
<html>
<body>
<!-- div class="blah" style="blahblah" -->
<span>
<p>test</p>
</span>
<!-- /div -->
</body>
</html>
It is key that the children nodes are copied and any attributes of the commented node are also copied.
The following is my best try but doesn't work. XSLT processor yells out: "Attribute and namespace nodes cannot be added to the parent element after a text, comment, pi, or sub-element node has already been added."
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- IdentityTransform -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
<xsl:copy>
<xsl:text disable-output-escaping="yes">--></xsl:text>
<xsl:apply-templates select="@* | node()"/>
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
</xsl:copy>
<xsl:text disable-output-escaping="yes">--></xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 1
Views: 1549
Reputation:
Its worth pointing out you can just use <xsl:comment>
to create comments in the output XML without having to worry about closing them correctly. What you've done could easily cause problems down the line if the closing comment delimiter wasn't put in correctly.
This will do the trick:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- IdentityTransform -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:comment>
<xsl:text> div </xsl:text>
<xsl:for-each select="@*">
<xsl:value-of select="local-name()"/>
<xsl:text>="</xsl:text>
<xsl:value-of select="."/>
<xsl:text>" </xsl:text>
</xsl:for-each>
</xsl:comment>
<xsl:apply-templates select="./*" />
<xsl:comment> /div </xsl:comment>
</xsl:template>
</xsl:stylesheet>
And when the output is pretty-printed, it gives this:
<html>
<body>
<!-- div class="blah" style="blahblah" -->
<span>
<p>test</p>
</span>
<!-- /div -->
</body>
</html>
Upvotes: 1
Reputation: 101690
It's a pretty ghastly use of XSLT, but this appears to work, and I can't think of a cleaner approach:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- IdentityTransform -->
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="div">
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:text disable-output-escaping="yes">--></xsl:text>
<xsl:apply-templates select="node()"/>
<xsl:text disable-output-escaping="yes"><!--</xsl:text>
</xsl:copy>
<xsl:text disable-output-escaping="yes">--></xsl:text>
</xsl:template>
</xsl:stylesheet>
Upvotes: 0