I\'ve been dealing with an API recently that requires nodes of the XML document to be in a particular order. I was wondering why they feel the need to enforce this when I ca
An enforced order makes it simpler for the consumer, which can look like:
consumeTransation:
consumeAddressIfPresent;
consumeAmountIfPresent;
consumeOrderIDIfPresent;
More significantly, the use of XML Schema for structure definition makes order more likely to be a requirement. That's because XML Schema has richer support for ordered lists (xs:sequence
) that for unordered lists (xs:all
). The latter have occurrence restrictions, are more difficult to validate, and are not extensible in the way sequences are. Some of that is improved in XML Schema 1.1, but most tools/APIs aren't there, yet.
One reason XML node order can matter is where an application is using a streaming parser. Having dependent elements in the expected order can allow the application to be significantly more efficient processing the XML data. This is especially true for applications processing large scale XML data.
Node order obviously matters in XML like this:
<p>
<span>This wouldn't make much sense</span>
<span>if the order of these nodes were reversed.</span>
</p>
It's less obvious in XML like what you provided, which appears to be some kind of serialization format. But objects whose property setters have side effects can fail if the properties aren't set in the right order.
Imagine a class with a private Person
field that exposes PersonID
and Name
properties. The PersonID
setter creates the private instance of Person
, and the Name
setter sets the Name
property on the private Person
field. In this case, setting Name
before you set PersonID
fails, because Person
doesn't exist yet.
This is a case where implementing a schema that requires PersonID
to appear before Name
in the XML keeps this error from happening, at the cost of forcing other developers to do things that are apparently nonsensical.
Tthe obvious thing to do in situations like this is to find the developer who wrote that class and beat him. This is rarely possible, though it's interesting to contemplate a world in which it were.
The answer lies in XML-DTD/Schema. The underlying schema so defined in the API results in the error. Though I suppose I donot wish to teach XML here, still a look at the following will make things clear.
XML has two points to be considered:
Points about DTD: Suggested DTD upon your question:
<!DOCTYPE transaction
[
<!ELEMENT address (#PCDATA)>
<!ELEMENT amount (#PCDATA)>
<!ELEMENT orderid (#PCDATA)>
]>
The above is a suggested DTD upon the structure you provided in the question. Since you are dealing with a particular API, it has such type of structure already defined in it. Alternative to this is the XML schema.
Points about XML Schema:
<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>
Currently, XML schema are used instead of DTDs as they are far more superior in defining the data structure for their users and provide an object-oriented approach.
It's faster and simpler for code to depend on the order of elements.
It can also prevent certain issues of ambiguity when the order is permitted to be arbitrary.
Besides, XML isn't meant as much for human readers, as it is meant for computer programs to consume. Computers don't mind doing things in order.