Search code examples
xmlxsltxsd

Transform XML from old schema to new schema?


I need to transform an XML document which does not use any schema to another format which uses a well defined schema.

So basically I have to transform this:

<healthCareFacilityTypeCode 
     displayName="Home" 
     codingScheme="Connect-a-thon healthcareFacilityTypeCodes"
    >Home</healthCareFacilityTypeCode>

Into this:

<healthCareFacilityTypeCode>
    <code>Home</code>
    <displayName>
        <LocalizedString value="Home" />
    </displayName>
    <schemeName>Connect-a-thon healthcareFacilityTypeCodes</schemeName>
</healthCareFacilityTypeCode>

I know how to transform it by hand by looking at the schema. Here is a snippet of the XSD:

<xsd:complexType name="DocumentEntryType">
    <xsd:sequence>
        <xsd:element minOccurs="0" 
                     name="healthCareFacilityTypeCode" 
                     type="tns:CodedMetadataType"/>
    </xsd:sequence>
    <xsd:attribute default="false" 
                   name="existing" 
                   type="xsd:boolean" 
                   use="optional"/>
</xsd:complexType>
<xsd:element name="DocumentEntry" type="tns:DocumentEntryType"/>

What I don't know how to tackle is: how to exploit the target XSD to transform a node from the source XML to the target XML doc. I feel all the info to perform the transform is located in the XSD but can I use it? how?


Solution

  • Followed suggestions and this is what I came up with. Not perfect but it is enough for my purpose.

        <xsl:template match="XDSDocumentEntry">
            <DocumentEntryType>
                <xsl:call-template name="namespaceChange"/>
                <xsl:apply-templates/>
            </DocumentEntryType>
        </xsl:template>
        <xsl:template match="node() | @*">
            <xsl:copy>
                <xsl:apply-templates select="node() | @*"/>
            </xsl:copy>
        </xsl:template>
        <xsl:template match="//*[matches(name(), 'Code')]">
            <xsl:copy>
                <code>
                    <xsl:value-of select="."/>
                </code>
                <schemeName>
                    <xsl:value-of select="@codingScheme"/>
                </schemeName>
                <displayName>
                    <LocalizedString>
                        <xsl:attribute name="value">
                            <xsl:value-of select="@displayName"/>
                        </xsl:attribute>
                    </LocalizedString>
                </displayName>
            </xsl:copy>
        </xsl:template>