Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing superfluous complex types in XML Schema using XSLT

Tags:

xslt

xsd

I've received a set of XML Schemas which contain "superfluous" complex types and I'm looking for a way to remove them using XSLT.

The schemas (see below) have a number of <xsd:element name="ElementX" type="ComplexTypeX"> tags, each which reference a complex type. Each complex type inherits from a base type in another schema (Datatypes.xsd), however does nothing to extend or restrict the type - hence being rather pointless!

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="..." xmlns:xsd="..." xmlns="...">
  <xsd:include schemaLocation="Datatypes.xsd" />

  <xsd:complexType name="ComplexType1">
    <xsd:simpleContent>
      <xsd:extension base="ActualType1" />
    </xsd:simpleContent>
  </xsd:complexType>
  <xsd:element name="ElementName1" type="ComplexType1" />

  <xsd:complexType name="ComplexType2">
    <xsd:simpleContent>
      <xsd:extension base="ActualType2" />
    </xsd:simpleContent>
  </xsd:complexType>
  <xsd:element name="ElementName2" type="ComplexType2" />

  ...
 </xsd:schema>

I'm trying (but not getting very far...) to write an XSLT transform to:

  • Replace the type of each element with the corresponding complex type's base type. E.g. the type of ElementName1 above would become ActualType1.

  • Remove the entire complexType from the output.

Producing output:

<?xml version="1.0" encoding="utf-8"?>
<xsd:schema targetNamespace="..." xmlns:xsd="..." xmlns="...">
  <xsd:include schemaLocation="Datatypes.xsd" />

  <xsd:element name="ElementName1" type="ActualType1" />

  <xsd:element name="ElementName2" type="ActualType2" />
  .
  .
  .
 </xsd:schema>

At the moment all the complexType elements don't alter the base type in any way so it is safe to perform the replacement. However, if in future, some of the complexType elements were changed to restrict or extend their base type (and have meaningful use), I would only like to perform the replacement/removal of the remaining superfluous types. Though I realise this will increase the complexity of the XSLT somewhat.

Background: The schemas have come from a third party and unfortunately I don't have any control of their production. I suspect the extra layer of complex types is present due to tooling used to produce the schemas.

Thanks!

like image 902
Jonny Rylands Avatar asked Mar 07 '26 17:03

Jonny Rylands


1 Answers

I'm trying (but not getting very far...) to write an XSLT transform to:

  • Replace the type of each element with the corresponding complex type's base type. E.g. the type of ElementName1 above would become ActualType1.

  • Remove the entire complexType from the output.

These two could be achieved by:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="complex" match="xsd:complexType" use="@name" />

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<!-- replace element type -->
<xsl:template match="xsd:element">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:attribute name="type">
            <xsl:value-of select="key('complex', @type)/xsd:simpleContent/xsd:extension/@base"/>
        </xsl:attribute>
        <xsl:apply-templates select="node()"/>
    </xsl:copy>
</xsl:template>

<!-- remove complexType -->
<xsl:template match="xsd:complexType"/>

</xsl:stylesheet>

I am afraid I did not understand this part:

However in the case some of the complexType elements were changed to restrict or extend their base type (and have some meaningful use), I would like to add a check for this before performing the replacement/removal.

like image 172
michael.hor257k Avatar answered Mar 10 '26 15:03

michael.hor257k