为什么节点顺序在XML中很重要?

时间:2011-09-16 18:01:00

标签: xml xsd

我最近一直在处理一个API,它要求XML文档的节点按特定顺序排列。我想知道为什么他们觉得有必要强制执行这个,因为我完全没有理由认为事情应该是这样的。

对于intance,这是正确的(xml大大简化)

<transaction>
    <address>1 main st</address>
    <amount>100</amount>
    <orderId>1234</orderId>
</transaction>

但这会返回错误

<transaction>
    <address>1 main st</address>
    <orderId>1234</orderId>
    <amount>100</amount>
</transaction>

起初我以为它们可以以列表/数组形式存储内容并使索引始终引用同一节点。我理解为什么以相同的顺序发送具有相同名称的兄弟节点是重要的,如解释in this question。但是,有些节点可以省略:

<transaction>
    <amount>100</amount>
    <orderId>1234</orderId>
</transaction>

所以在第三个例子中,在第一个(正确的)例子中,amount和orderId现在位于[0]和[1]而不是[1]和[2]。

另一个想法是他们将XML作为一个字符串处理并要求他们总是知道哪些节点在彼此之后,但是再次允许省略节点,这个理论没有意义。

有人可以向我解释为什么我给节点的顺序很重要吗?或者我只是处理一个老而脾气暴躁的API?

5 个答案:

答案 0 :(得分:17)

节点顺序显然在XML中很重要:

<p>
   <span>This wouldn't make much sense</span>
   <span>if the order of these nodes were reversed.</span>
</p>

在XML中不像你提供的那样明显,这似乎是某种序列化格式。但是,如果未按正确的顺序设置属性,则属性设置器具有副作用的对象可能会失败。

想象一个具有私有Person字段的类,该字段公开PersonIDName属性。 PersonID setter创建Person的私有实例,Name setter在私有Name字段上设置Person属性。在这种情况下,在设置Name之前设置PersonID失败,因为Person尚不存在。

这种情况下,实现需要PersonID出现在XML Name之前的模式可以防止此错误发生,代价是迫使其他开发人员做一些显然荒谬的事情。

在这种情况下,显而易见的事情就是找到那个写这个课并打败他的开发人员。这很难实现,尽管考虑一个它所处的世界很有意思。

答案 1 :(得分:5)

XML节点顺序可能很重要的一个原因是应用程序正在使用流式解析器。具有预期顺序的依赖元素可以允许应用程序更有效地处理XML数据。对于处理大规模XML数据的应用程序尤其如此。

答案 2 :(得分:2)

答案在于 XML-DTD / Schema 。 API中定义的基础架构导致错误。虽然我想我不想在这里教XML,但是看看以下内容会让事情变得清晰。

XML有两点需要考虑:

  • 格式良好的XML:完美语法
  • 有效的XML:对DTD(文档类型定义)/架构完全有效

关于DTD的要点: 根据您的问题建议DTD:

<!DOCTYPE transaction
[
<!ELEMENT address (#PCDATA)>
<!ELEMENT amount (#PCDATA)>
<!ELEMENT orderid (#PCDATA)>
]>

以上是您在问题中提供的结构的建议DTD。由于您正在处理特定的API,因此它已经定义了这种类型的结构。替代方案是 XML架构

有关XML架构的要点:

<xs:element name="transaction">    
<xs:complexType>
  <xs:sequence>
    <xs:element name="address" type="xs:string"/>
    <xs:element name="amount" type="xs:string"/>
    <xs:element name="orderid" type="xs:string"/>
  </xs:sequence>
</xs:complexType>
</xs:element>

目前, XML架构使用而不是DTD ,因为它们在为用户定义数据结构方面更为出色,并提供面向对象的方法

答案 3 :(得分:1)

代码依赖于元素的顺序更快更简单。

当订单允许任意时,它也可以防止某些歧义问题。

此外,XML并不意味着人类读者,因为它意味着计算机程序要消费。计算机不介意按顺序做事。

答案 4 :(得分:1)

强制订单使消费者更加简单,如下所示:

consumeTransation:
    consumeAddressIfPresent;
    consumeAmountIfPresent;
    consumeOrderIDIfPresent;

更重要的是, XML Schema 用于结构定义使订单更有可能成为要求。这是因为XML Schema对无序列表(xs:sequence)的有序列表(xs:all)提供了更丰富的支持。后者具有发生限制,更难以验证,并且在序列的方式上不可扩展。其中一些在XML Schema 1.1中有所改进,但大多数工具/ API尚未出现。