I have a large XSD, with elements that look like this:
<xs:element name="ProgramName" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>PN</xs:documentation>
</xs:annotation>
</xs:element>
<xs:element name="TestItem" type="xs:string" minOccurs="0">
<xs:annotation>
<xs:documentation>TA</xs:documentation>
</xs:annotation>
</xs:element>
I would like to collapse the <documentation>
element into an attribute of the grandparent element, like this:
<xs:element name="ProgramName" type="xs:string" minOccurs="0" code="PN">
</xs:element>
<xs:element name="TestItem" type="xs:string" minOccurs="0" code="TA">
</xs:element>
How could this be done with XSLT? Alternatively, is there a better (read: simpler) way to do it than XSLT?
The resulting XSD will be used with XSD.EXE
to create a C# class, for serialization and deserialization purposes. The original XSD cannot be used this way, because XSD.EXE
drops all of the annotation elements, so the information contained in those annotations is lost.
This is how I'd do it:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*[xs:annotation]">
<xsl:copy>
<xsl:attribute name="code"><xsl:value-of select="xs:annotation/xs:documentation"/></xsl:attribute>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xs:annotation"/>
</xsl:stylesheet>
This Just another answer :)
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="node()[local-name()='element']">
<xsl:copy>
<xsl:apply-templates select="@*|node()[local-name()!='annotation']"/>
<xsl:for-each select="node()[local-name()='annotation']/node()[local-name()='documentation']">
<xsl:attribute name="code">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Indeed a very good thought of using XSLT for rearranging nodes rather than doing it manually :) I always make use of XSLT ..
We can even use it to generate sample XMLs from XSD .. if XSD is with bearable size :)
<xs:element/>
.. instead if they define complextype else where and use it as type for Element it should work - InfantPro'Aravind' 2012-04-07 09:22