Xsd DTD与XMLSchema的等价性
我一直认为XMLSchema和DTD是等价的,但在建模复杂关系(如继承)时,使用后者更麻烦 最近,我想构建一个模式来验证具有如下结构的文档:Xsd DTD与XMLSchema的等价性,xsd,dtd,Xsd,Dtd,我一直认为XMLSchema和DTD是等价的,但在建模复杂关系(如继承)时,使用后者更麻烦 最近,我想构建一个模式来验证具有如下结构的文档: <data> <array> <int></int> <int></int> </array> </array> <float></float> <float></float> &l
<data>
<array>
<int></int>
<int></int>
</array>
</array>
<float></float>
<float></float>
</array>
<int><int>
<float></float>
</data>
中的元素可以以任何顺序出现,每个元素的基数为0*
使用XMLSchema,如果我使用<!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,因为我无法验证元素数据,除非非常松散。这让人松了一口气。