How do I convert these embedded elements to the attributes of the parent element?
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 an element <documentation>
into an attribute of the grandparent element, for example:
<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 can this be done with XSLT? Alternatively, is there a better (read: simpler) way to do this 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 in this way because it XSD.EXE
removes all annotation elements, so the information contained in those annotations is lost.
source to share
This is how I would 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>
source to share
This is 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, it is a very good idea to use XSLT to reorder nodes rather than doing it manually :) I always use XSLT ..
We can even use it to generate XML samples from XSD .. if the XSD is sized correctly :)
source to share