有没有办法在XML Schema中强制/保留XML元素的顺序?

时间:2010-05-26 10:07:30

标签: xml xsd

让我们考虑以下XML Schema:

<?xml version="1.0" encoding="UTF-8"?>
<schema 
    targetNamespace="http://www.example.org/library" 
    elementFormDefault="qualified" 
    xmlns="http://www.w3.org/2001/XMLSchema" 
    xmlns:lib="http://www.example.org/library">

    <element name="library" type="lib:libraryType"></element>

    <complexType name="libraryType">
        <sequence>
            <element name="books" type="lib:booksType"></element>
        </sequence>
    </complexType>

    <complexType name="booksType">
        <sequence>
            <element name="book" type="lib:bookType" 
                     maxOccurs="unbounded" minOccurs="1"></element>
        </sequence>
    </complexType>

    <complexType name="bookType">
        <attribute name="title" type="string"></attribute>
    </complexType>
</schema>

和相应的XML示例:

<?xml version="1.0" encoding="UTF-8"?>
<lib:library 
    xmlns:lib="http://www.example.org/library" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://www.example.org/library src/library.xsd ">

  <lib:books>
    <lib:book title="t1"/>
    <lib:book title="t2"/>
    <lib:book title="t3"/>
  </lib:books>

</lib:library>

有没有办法保证保留<lib:book .../>元素的顺序?我想确保读取XML的任何解析器都会返回指定oder中的书籍,首先是带有title="t1"的书籍,然后是带有title="t2"的书籍,最后是带有{{1}的书籍}。

据我所知,XML解析器不需要保留顺序。我想知道是否可以通过XML Schema强制执行此操作?对我来说,一个快速的解决方案是向title="t3"元素添加index属性,并将订单保留委托给读取XML的应用程序。

评论?建议?

4 个答案:

答案 0 :(得分:7)

根据Michael Kay的说法,他似乎是XML世界中的重要人物。

  

是的,您可以假设将保留元素的顺序。 XML规范的编写者没有明确地说明这一点,但那是因为他们认为这很明显。没有保留顺序的解析器可能在技术上符合要求,但没有人会使用它;许多XML应用程序依赖于保留的顺序,特别是那些使用XML来表示文档的程序。

来源:http://lists.xml.org/archives/xml-dev/201003/msg00045.html

答案 1 :(得分:2)

我知道这是非常古老的,但不过,我也在寻找一种方法来保证XML元素的保留顺序。

虽然所有当前的解析器都可能保留顺序,但XML定义绝不需要这样,而且未来的解析器可能会完全不同地处理订单。

现在最好的解决方案似乎是给元素一个'id'属性,以便在解析后可以在代码中验证排序。

我不想要求我的用户添加任意​​id =“1”,id =“2”等,当XML文件中的订单已经明显时,但据我所知,没有官方标准在XML中需要重复元素的特定顺序。

<强>更新

如果你正在使用.NET,它有一个属性,你可以设置它来定义它读取这些元素的顺序。所以,我想只要你知道你的XML将被解析的位置,并且解析器支持执行按要求的方式排序元素,然后可以强制执行订单。

但是,如果第三方采用并尝试使用自己的解析器复制结果,则可能会产生混淆,因为该命令是在其他地方配置的,而不是在XML中,因此没有其他解析器实现会知道利用它顺序。

因此,这可以概括为:(a)订单不能在XML规范本身内强制执行,但是(b)订单可以并且通常由大量的XML解析器强制执行。

答案 2 :(得分:2)

正如上面的评论所述, xs:sequence定义了一个ORDERED集合。以下是证据:

<xsd:complexType name="USAddress">
   <xsd:sequence>
    <xsd:element name="name"   type="xsd:string"/>
    <xsd:element name="street" type="xsd:string"/>
    <xsd:element name="city"   type="xsd:string"/>
    <xsd:element name="state"  type="xsd:string"/>
    <xsd:element name="zip"    type="xsd:decimal"/>
   </xsd:sequence>
   <xsd:attribute name="country" type="xsd:NMTOKEN" fixed="US"/>
</xsd:complexType>
     

...这些元素必须被称为名称,街道,城市,州和邮政编码,由声明的名称属性的值指定,并且元素必须以相同的顺序(顺序)出现在它们中宣布

来源W3C: XML Schema Part 0

答案 3 :(得分:1)

元素的顺序(与属性不同)在XML中很重要,我知道的每个解析器都会保留它。