我最近一直在处理一个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?
答案 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
字段的类,该字段公开PersonID
和Name
属性。 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有两点需要考虑:
关于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尚未出现。