以编程方式将 XSD 1.1 架构转换为 XSD 1.0?

Programmatically convert an XSD 1.1 schema to XSD 1.0?

如何通过剥离所有 1.1 功能并仅保留与 XSD 1.0 兼容的子集,将 XSD 1.1 模式自动转换为 XSD 1.0 模式?

我意识到这会限制您可以利用多少 XSD 1.1 功能,但我想象的用例是您同时发布 XSD 1.1 的模式版本和更兼容的 XSD 1.0 版本,两者描述相同的数据结构,但 1.1 版本有一些额外的 <assert> 数据完整性检查。

如您所料,无法进行一般大小写转换。但是,鉴于您可以控制 v1.1 XSD,还是有希望的。 Appendix G.1 of the XSD v1.1 Recommendation 总结了与 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>

如果您正在设想同时发布 1.1 模式和相关的 1.0 模式,那么最简单和最好的方法可能是使用 vc: XSD 1.1 规范中描述的命名空间.您可以使用 vc: 命名空间来标记 1.1 功能,例如您提到的断言(或包含它们的声明),并提供 1.0 等价物或接近等价物。

我们可以使用它来将 XSD 1.1 规范中的示例中的 xs:assert 标记为仅 1.1 的功能:

<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 stylesheet that does the job (full disclosure; I wrote it). There used to be a working online demo as well, but I see that bit rot has set in, and it doesn't seem to work in current browsers; I'll fix it when I have time. The documentation 可能仍然有用。