如何通过剥离所有 1.1 功能并仅保留与 XSD 1.0 兼容的子集来自动将 XSD 1.1 架构转换为 XSD 1.0 架构?
我意识到这会限制您可以利用多少 XSD 1.1 功能,但我想象的用例是一个模式,您可以在其中发布 XSD 1.1 版本和更兼容的 XSD 1.0 版本,两者都描述了相同的数据结构,但 1.1 版本具有一些额外的<assert>
数据完整性检查。
如果您想同时发布 1.1 模式和相关的 1.0 模式,那么可能最简单和最好的方法是使用 XSD 1.1 规范中描述的 vc: 命名空间。您可以使用 vc: 命名空间来标记 1.1 功能,例如您提到的断言(或包含它们的声明),并提供 1.0 等价物或接近等价物。
我们可以使用它来xs:assert
将 XSD 1.1 规范中的示例标记为 1.1-only 功能:
<xs:complexType name="arrayType">
<xs:sequence>
<xs:element name="entry" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="length" type="xs:int"/>
<xs:assert test="@length eq fn:count(./entry)"
xmlns:vc="http://www.w3.org/2007/XMLSchema-versioning"
vc:minVersion="1.1"/>
</xs:complexType>
任何 XSD 1.1 处理器都需要理解 vc: 命名空间并相应地过滤模式文档(接受 vc:minVersion 小于或等于 1.1 或 vc:maxVersion 大于 1.1 的内容,等等)。因此,具有 vc:* 属性的模式文档可以作为 1.1 模式提供。
可以更新符合标准的 1.0 处理器以理解 vc: 命名空间,但我不知道有什么。因此,为了供 1.0 处理器使用,模式文档需要在他们看到之前进行过滤。
与 kjhughes 一样,我认为 XSLT 样式表可能是您进行过滤的最佳选择。但是使用 vc:* 命名空间可以很容易地可靠地完成,并且不需要模式作者为了简化转换而最小化 1.1 特性的使用。
编写样式表来执行必要的过滤很容易,但实际上您不必这样做:有一个XSLT 1.0 样式表可以完成这项工作(完全公开;我编写了它)。以前也有一个可以运行的在线演示,但是我看到有点腐烂了,而且它似乎在当前的浏览器中不起作用;有时间我会修的。该文档可能仍然有用。
如您所料,一般情况下的转换是不可能的。但是,鉴于您可以控制 v1.1 XSD,还是有希望的。 XSD v1.1 建议的附录 G.1总结了与 XSD v1.0 相比的变化。简而言之,不要依赖附录 G.1 中描述的任何新结构或行为。
如果除了xsd:assert
提到的使用之外,您还清楚所有更改,您可以使用简单的 XSLT 转换来维护从 v1.0 XSD 到 v1.1 XSD 的映射:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="xsd:assert"/>
</xsl:stylesheet>