xml - Add namespace to root node when root node may have multiple types -
i using xlst 1.0 , want transform xml add 'nil' attributes empty elements. finding namespace being added each matching element e.g output looks like: <age xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:nil="true" />
i know valid i'd rather added top-node. came across answer: how can add namespaces root element of xml using xslt?
however have multiple possible root nodes, thought this:
<xsl:template match="animals | people | things"> <xsl:element name="{name()}"> <xsl:attribute name="xmlns:xsi">http://www.w3.org/2001/xmlschema-instance</xsl:attribute> <xsl:apply-templates/> </xsl:element> </xsl:template>
however error visual studio "prexix xmlns not defined" , i'm not sure this.
here total xlst file (it won't paste reason) tries few things:
- transform different types of animal single type
- add namespace root node
- add
xsi:nil = true
empty elements (note must have no children not no text, or top-level node gets transformed)
first, namespace declaration not attribute, , cannot created using xsl:attribute
instruction.
you can use xsl:copy-of
insert namespace declaration "manually" @ desired location, example:
xslt 1.0
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/*"> <xsl:copy> <xsl:copy-of select="document('')/xsl:stylesheet/namespace::xsi"/> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="*[not(node())]"> <xsl:copy> <xsl:attribute name="xsi:nil">true</xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>
however, results rather processor- dependent. xalan, example, ignore instruction , repeat declaration @ every empty node outputs before. in general, have little no control on how xslt processor serializes output.
another option use namespace declaration @ root level, say:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance"> <xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/> <xsl:strip-space elements="*"/> <!-- identity transform --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <xsl:template match="/*"> <xsl:copy> <xsl:attribute name="xsi:nil">false</xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="*[not(node())]"> <xsl:copy> <xsl:attribute name="xsi:nil">true</xsl:attribute> <xsl:apply-templates/> </xsl:copy> </xsl:template> </xsl:stylesheet>
this worked processors have tested (ymmv).
of course, best option nothing, since have noted, difference purely cosmetic.
Comments
Post a Comment