我收到了一组XML Schema,其中包含"多余的"复杂的类型,我正在寻找一种使用XSLT删除它们的方法。
模式(见下文)有许多<xsd:element name="ElementX" type="ComplexTypeX">
个标签,每个标签都引用一个复杂的类型。每个复杂类型都继承自另一个模式(Datatypes.xsd)中的基类型,但是不会扩展或限制类型 - 因此没有多大意义!
<?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>
我尝试(但不是很远......)将XSLT转换写入:
用相应的复杂类型的基本类型替换每个元素的类型。例如。上面的ElementName1的类型将变为ActualType1。
从输出中删除整个complexType。
制作输出:
<?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>
目前,所有complexType元素都不会以任何方式更改基本类型,因此可以安全地执行替换。但是,如果将来某些complexType元素被更改为限制或扩展其基类型(并且具有有意义的用途),我只想执行替换/删除剩余的多余类型。虽然我意识到这会在某种程度上增加XSLT的复杂性。
背景:这些模式来自第三方,不幸的是我无法控制他们的产品。我怀疑由于用于生成模式的工具而存在额外的复杂类型层。
谢谢!
答案 0 :(得分:1)
我正在尝试(但不是很远......)编写XSLT转换 致:
用相应的复杂类型的基本类型替换每个元素的类型。例如。上面的ElementName1的类型将成为 ActualType1。
从输出中删除整个complexType。
这两个可以通过以下方式实现:
<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>
恐怕我不明白这一部分:
但是在某些complexType元素被更改为的情况下 限制或扩展他们的基本类型(并有一些有意义的用途),我 我希望在执行之前添加一个检查 更换/移除。
答案 1 :(得分:1)
你似乎想要这样的东西:
<?xml version="1.0" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<!-- anything not otherwise matched gets copied -->
<xsl:template match="@*|node()">
<xsl:apply-templates select="." mode="literal"/>
</xsl:template>
<xsl:template match="@*|node()" mode="attribute-filter">
<xsl:apply-templates select="." mode="literal"/>
</xsl:template>
<xsl:template match="@*|node()" mode="literal">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- in mode 'attribute-filter', 'name' and 'type' attributes transform to nothing -->
<xsl:template match="@name|@type" mode="attribute-filter">
<!-- transforms to nothing -->
</xsl:template>
<!-- keep only meaningful extension types -->
<xsl:template match="/xsd:schema/xsd:complexType[./xsd:simpleContent/xsd:extension]">
<xsl:if test="boolean(./xsd:simpleContent/xsd:extension/node())">
<!-- a bona fide extension -->
<xsl:apply-templates select="." mode="literal"/>
</xsl:if>
<!-- else it transforms to nothing -->
</xsl:template>
<!-- patch up element declarations where necessary -->
<xsl:template match="xsd:element[@type]">
<xsl:variable name="typename" select="@type" />
<xsl:choose>
<xsl:when test="not(/xsd:schema/xsd:complexType[@name = $typename]/xsd:simpleContent)">
<xsl:apply-templates select="." mode="literal"/>
</xsl:when>
<xsl:when test="boolean(/xsd:schema/xsd:complexType[@name = $typename]/xsd:simpleContent/xsd:restriction)">
<xsl:apply-templates select="." mode="literal"/>
</xsl:when>
<xsl:when test="boolean(/xsd:schema/xsd:complexType[@name = $typename]/xsd:simpleContent/xsd:extension/node())">
<xsl:apply-templates select="." mode="literal"/>
</xsl:when>
<xsl:otherwise>
<xsl:element name="xsd:element">
<xsl:copy-of select="@name" />
<xsl:attribute name="type">
<xsl:value-of select="/xsd:schema/xsd:complexType[@name = $typename]/xsd:simpleContent/xsd:extension/@base"/>
</xsl:attribute>
<xsl:apply-templates select="@*|node()" mode="attribute-filter"/>
</xsl:element>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
假设不需要的complexType声明都使用简单内容的“扩展”替代方法,如示例所示,但它也可以扩展为也处理其他不需要的类型。