xslt - Maintaining XML comments during XSL Transformations -
xml
<?xml-stylesheet type="text/xsl" href="script.xsl"?> <elements> <stack> <name>ray</name> <status>0</status> </stack> <!-- comment 1 --> <things> <!-- comment 2 --> <thing> <color>red</color> <!-- state comment --> <state>solid</state> <!-- weight comment --> <weight>45</weight> <unit>34</unit> <!-- comment 3 --> </thing> </things> <favs> <stick>ready</stick> <!-- comment 4--> </favs> </elements>
expected output
<elements> <stack> <name>ray</name> <status>0</status> </stack> <!-- comment 1 --> <mainelements> <!-- comment 2 --> <specialthing> <!-- weight comment --> <propertyone>45</propertyone> <propertytwo>red</propertytwo> <!-- state comment --> <propertythree>solid</propertythree> </specialthing> <!-- comment 3 --> </mainelements> <favs> <stick>ready</stick> <!-- comment 4--> </favs> </elements>
current xsl
<?xml version="1.0" encoding="utf-8" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="things"> <mainelements> <xsl:apply-templates select="thing"/> </mainelements> </xsl:template> <xsl:template match="thing"> <specialthing> <xsl:apply-templates select="weight"/> <xsl:apply-templates select="color"/> <xsl:apply-templates select="state"/> </specialthing> </xsl:template> <xsl:template match="weight"> <propertyone> <xsl:value-of select="."/> </propertyone> </xsl:template> <xsl:template match="color"> <propertytwo> <xsl:value-of select="."/> </propertytwo> </xsl:template> <xsl:template match="state"> <propertythree> <xsl:value-of select="."/> </propertythree> </xsl:template> </xsl:stylesheet>
i not able indent output mentioned in output. main thing want achieve maintain comments of tags maintained in output.
eg: tag named weight renamed "propertyone" , value maintained in output. comment above same missing. want keep comment of same in output also. how can achieve that?
you'll have xsl:apply-templates
preceding sibling comment()
's. since you're changing order of weight
/color
/state
, you'll have add each 1 of templates.
also, matching comment 3
tricky , did might not work actual data.
xml input
<elements> <stack> <name>ray</name> <status>0</status> </stack> <!-- comment 1 --> <things> <!-- comment 2 --> <thing> <color>red</color> <!-- state comment --> <state>solid</state> <!-- weight comment 1 --> <!-- weight comment 2 --> <weight>45</weight> <unit>34</unit> <!-- comment 3 --> </thing> </things> <favs> <stick>ready</stick> <!-- comment 4--> </favs> </elements>
xslt 1.0
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <xsl:strip-space elements="*"/> <xsl:template match="node()|@*"> <xsl:copy> <xsl:apply-templates select="node()|@*"/> </xsl:copy> </xsl:template> <xsl:template match="things"> <mainelements> <xsl:apply-templates select="thing|comment()"/> </mainelements> </xsl:template> <xsl:template match="thing"> <specialthing> <xsl:apply-templates select="weight"/> <xsl:apply-templates select="color"/> <xsl:apply-templates select="state"/> </specialthing> <xsl:apply-templates select="comment()[not(following-sibling::*)]"/> </xsl:template> <xsl:template match="weight"> <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/> <propertyone> <xsl:value-of select="."/> </propertyone> </xsl:template> <xsl:template match="color"> <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/> <propertytwo> <xsl:value-of select="."/> </propertytwo> </xsl:template> <xsl:template match="state"> <xsl:apply-templates select="preceding-sibling::comment()[generate-id(following-sibling::*[1])=generate-id(current())]"/> <propertythree> <xsl:value-of select="."/> </propertythree> </xsl:template> </xsl:stylesheet>
xml output
<elements> <stack> <name>ray</name> <status>0</status> </stack> <!-- comment 1 --> <mainelements> <!-- comment 2 --> <specialthing> <!-- weight comment 1 --> <!-- weight comment 2 --> <propertyone>45</propertyone> <propertytwo>red</propertytwo> <!-- state comment --> <propertythree>solid</propertythree> </specialthing> <!-- comment 3 --> </mainelements> <favs> <stick>ready</stick> <!-- comment 4--> </favs> </elements>
Comments
Post a Comment