Xsd DTD与XMLSchema的等价性

Xsd DTD与XMLSchema的等价性,xsd,dtd,Xsd,Dtd,我一直认为XMLSchema和DTD是等价的,但在建模复杂关系(如继承)时,使用后者更麻烦 最近,我想构建一个模式来验证具有如下结构的文档: <data> <array> <int></int> <int></int> </array> </array> <float></float> <float></float> &l

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

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

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

中的元素可以以任何顺序出现,每个元素的基数为0* 使用XMLSchema,如果我使用定义复杂类型,我可以使元素无序,但最大基数为1xs:sequence>和是其他明显的候选项,但它们比我想要的限制性更强

然后我注意到DTD似乎能够实现这样的效果:

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


有什么方法可以构建一个等价的模式,或者我必须在这里使用DTD吗?

只有在保持元素顺序的情况下,才可以使用XSD(因此可以使用xs:sequence)。我的意思是,浮点数总是在数组(如果有的话)之后,int总是在浮点数(如果有的话)之后,考虑到你可以根据自己的意愿对每种类型重复任意多个眼圈(或者完全忽略它们)

原因是XSD xs:all复杂类型不支持其任何内容类型(元素、其他嵌套组类型等)的无界属性。其他更“宽松”的模式将允许您这样做,例如,在您声明时使用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>

只有在保持元素顺序的情况下(因此可以使用xs:sequence),才可以使用XSD。我的意思是,浮点数总是在数组(如果有的话)之后,int总是在浮点数(如果有的话)之后,考虑到你可以根据自己的意愿对每种类型重复任意多个眼圈(或者完全忽略它们)

原因是XSD xs:all复杂类型不支持其任何内容类型(元素、其他嵌套组类型等)的无界属性。其他更“宽松”的模式将允许您这样做,例如,在您声明时使用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>

我想我会回到这个问题上来,因为前面的答案不正确。 事实上,使用XML模式可以解决最初的问题

正确的方法是定义一个组元素,该元素包含所有不同选项(整数、浮点、数组)之间的选择,并且每个选项的基数为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模式得到了更好的支持。我已经精心设计了一个基于RelaxNG的解析器来解决最初的问题,但是可用的验证器(如JING)比使用Java等人提供的基于XML模式的工具要笨重得多。

我想我会回到这个问题上来,因为前面的答案不正确。 事实上,使用XML模式可以解决最初的问题

正确的方法是定义一个组元素,该元素包含所有不同选项(整数、浮点、数组)之间的选择,并且每个选项的基数为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模式得到了更好的支持。我已经设计了一个基于RelaxNG的解析器来解决最初的问题,但是可用的验证器(如JING)比使用Java等人提供的基于XML模式的工具要笨重得多。

谢谢Fernando。由于生成数据的方式不同,我无法假设特定的序列,因此我将考虑一些替代方案。我不想使用DTD,因为我无法验证元素数据,除非非常松散。那就让我们祈祷吧。谢谢你,费尔南多。由于生成数据的方式不同,我无法假设特定的序列,因此我将考虑一些替代方案。我不想使用DTD,因为我无法验证元素数据,除非非常松散。这让人松了一口气。