我一直都认为XMLSchemas和DTD是等价的,但后者在建模复杂关系(如继承)时使用起来比较麻烦。
最近我想构建一个模式来验证具有如下结构的文档:
<data>
<array>
<int></int>
<int></int>
</array>
</array>
<float></float>
<float></float>
</array>
<int><int>
<float></float>
</data>
里面的元素&lt;数据&gt;可以按任何顺序出现,每个都是基数0 .. * 使用XMLSchema,如果我使用&lt;定义复杂类型xs:全部&gt;我可以使这些元素无序,但最大基数为1。 xs:sequence&gt;和&lt; xs:choice&gt;是其他明显的候选人,但他们比我想要的更具限制性。
然后我注意到DTD似乎能够像这样实现:
<!ELEMENT data (array | float | int)*>
有没有办法构建一个等效的模式,还是我必须在这里使用DTD?
答案 0 :(得分:1)
只有保留元素的顺序才能通过XSD实现(因此可以使用 xs:sequence )。我的意思是, float 总是会出现在数组之后(如果有的话),并且 int 总是会出现在 float之后(如果有的话),考虑到你可以按照你想要的每种类型重复多次(或完全省略它们)。
原因是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>
答案 1 :(得分:0)
我以为我会回到这里,因为之前的答案是错误的。 事实上,人们可以使用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的工具更加笨重。