XML自体は順序を保証する形式ではなく、要素の順序がデータの意味や正当性に影響を与えない場合が多い形式です。しかし、DTD (Document Type Definition) や XML Schema などのスキーマ定義がある場合、そのスキーマによって順序を強制することが可能です。
DTDにおける要素順序の制約
DTDでは、要素の出現順序を定義することで、順序を保証するような構造を指定できます。ただし、これはXMLドキュメントを「バリデート」した場合にのみ有効で、DTDがあるだけでは順序の強制は行われません。
例: DTDで要素の順序を定義
以下のDTDでは、name → age → city の順序で要素が記述されることを要求しています。
DTD例
<!ELEMENT person (name, age, city)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT city (#PCDATA)>
対応するXMLドキュメント
<person>
<name>Alice</name>
<age>30</age>
<city>New York</city>
</person>
上記のDTDに基づいてバリデーションを行った場合、以下のようなXMLは「無効」と判定されます。
無効なXML例
<person>
<city>New York</city>
<name>Alice</name>
<age>30</age>
</person>
DTDの順序指定の特徴
順序が保証される: DTDで定義した要素順序に違反すると、XMLパーサがエラーを報告します。ただし、順序が保証されるのはDTDを使用してドキュメントをバリデーションした場合のみです。
順序指定の柔軟性: DTDでは次のような順序ルールが設定可能です:
固定順序 ((name, age, city))
任意の順序・繰り返し ((name | age | city)*)
XML Schemaでの順序制御
XML Schemaでは、DTDよりも柔軟かつ厳密に順序を制御できます。たとえば、 を使って要素の出現順序を固定できます。
XML Schema例
<xs:element name="person">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string" />
<xs:element name="age" type="xs:integer" />
<xs:element name="city" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
対応するXMLドキュメント
<person>
<name>Alice</name>
<age>30</age>
<city>New York</city>
</person>
DTDやXML Schemaの限界
1. 順序の強制はバリデーション時のみ有効:
XML自体の仕様では順序を保証しません。DTDやSchemaで順序を指定し、それに基づいてバリデーションを行う必要があります。
2. データ操作の順序保証には影響しない:
パース後のデータ構造(例: HashMap)に順序が保持されるわけではありません。パーサやライブラリがデータをどのように格納するかは実装依存です。
順序を保持したい場合は、LinkedHashMapやリストなどを使用する必要があります。
結論
DTDやXML Schemaがあれば順序を保証できるのか?
スキーマがある場合、定義された順序を強制できます。ただし、それはバリデーション時に限ります。
順序を保証した操作をしたい場合はどうするか?
バリデーションに加えて、データを順序を保持するデータ構造(例: LinkedHashMap)にパースすることで、順序を完全に制御できます。
DTDやスキーマによって要素順序を強制しつつ、パース後のデータも順序を保持したい場合、ライブラリの選定やカスタム処理が必要です。