【问题标题】:Equivalence of DTDs and XMLSchemasDTD 和 XMLSchema 的等价性
【发布时间】:2009-04-07 06:40:49
【问题描述】:

我一直认为 XMLSchema 和 DTD 是等价的,但后者在建模复杂关系(如继承)时使用起来更麻烦。

最近我想构建一个模式来验证具有如下结构的文档:

<data>
 <array>
   <int></int>
   <int></int>
 </array>
 </array>
   <float></float>
   <float></float>
 </array>
 <int><int>
 <float></float>
</data>

中的元素可以按任意顺序出现,每个元素的基数都是0..* 使用 XMLSchema,如果我使用 定义复杂类型,我可以让元素乱序,但最大基数为 1。 和 是其他明显的候选者,但它们是比我想要的更严格。

然后我注意到 DTD 似乎能够像这样实现这一点:

<!ELEMENT data (array | float | int)*>

有什么方法可以构建一个等效的模式,还是我必须在这里使用 DTD?

【问题讨论】:

    标签: xsd dtd


    【解决方案1】:

    只有在保持元素顺序的情况下才能通过 XSD 实现(因此您可以使用 xs:sequence)。我的意思是,一个 float 总是在一个 array 之后(如果有的话),并且一个 int 总是在一个 float 之后(如果有的话),考虑到您可以根据需要对每种类型重复多次(或完全省略它们)。

    原因是 XSD xs:all 复杂类型不支持其任何内容类型(元素、其他嵌套组类型等)的 unbounded 属性。其他更“宽松”的模式将允许您这样做,例如您所说的 DTD,或例如 RelaxNG。

    这是一个适合您的 XML 文件的示例 XSD:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified" attributeFormDefault="unqualified">
        <xs:complexType name="arrayType">
                <xs:sequence>
                    <xs:element name="array" type="arrayType" minOccurs="0" maxOccurs="unbounded"/>
                    <xs:element name="int" minOccurs="0" maxOccurs="unbounded"/>
                    <xs:element name="float" minOccurs="0" maxOccurs="unbounded"/>
                </xs:sequence>
        </xs:complexType>
        <xs:element name="data" type="arrayType"/>
    </xs:schema>
    

    【讨论】:

    • 谢谢费尔南多。由于数据的生成方式,我不能假设特定的序列,所以我会看看一些替代方案。我不想使用 DTD,因为我无法验证元素数据,除非非常松散。这让 RelaxNG 手指交叉
    【解决方案2】:

    我想我会回到这个问题,因为之前的答案不正确。 事实上,使用 XML Schema 可以解决原来的问题。

    正确的方法是定义一个组元素,它包含所有各种选项(整数、浮点数、数组)之间的选择,并且每个选项的基数为 0..*.

    <xs:group name="dataTypesGroup">
        <xs:choice>
            <xs:element name="int" type="intType"/>
            <xs:element name="float" type="floatType"/>
            <xs:element name="array">
                <xs:complexType>
                    <xs:choice>
                        <xs:element name="int" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
                        <xs:element name="float" type="xs:float" minOccurs="0" maxOccurs="unbounded"/>
                    </xs:choice>
                    <xs:attribute name="id" use="required"></xs:attribute>
                </xs:complexType>    
            </xs:element>
        </xs:choice>
    </xs:group>
    

    从这里开始,仍然需要在 complexType 定义中引用组并将组的基数设置为 0..*

    <xs:element name="data" minOccurs="0" maxOccurs="unbounded">
        <xs:complexType>
            <xs:group ref="dataTypesGroup" minOccurs="0" maxOccurs="unbounded"/>
        </xs:complexType>
    </xs:element>
    

    等等。有点冗长(尤其是与 RelaxNG 的语法相比),但好处是 XML Schema 得到了更好的支持。我制作了一个基于 RelaxNG 的解析器来解决最初的问题,但可用的验证器(如 JING)比使用 Java 等附带的基于 XML Schema 的工具要笨重。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-12
      • 2018-11-19
      • 1970-01-01
      • 2015-04-12
      • 2018-02-23
      • 1970-01-01
      • 2015-11-15
      • 2018-06-28
      相关资源
      最近更新 更多