XMLからJSON:見た目より難しい
XMLとJSON間の変換がなぜ驚くべき結果を生むか、そしてエッジケースの扱い方。
XMLデータがあります。JavaScriptアプリはJSONが必要。変換して進むだけ、でしょう?
変換が予期しない結果を生むことを除いて。存在すべき配列が存在しない。属性が変な場所に。単一アイテムがランダムに配列になる。
XMLとJSONはデータを異なる方法でモデル化。間を変換するには決定が必要。
根本的な不一致
JSONにあるもの:オブジェクト、配列、文字列、数値、ブール、null。
XMLにあるもの:要素、属性、テキストコンテンツ、名前空間、コメント、CDATA。
1対1のマッピングはありません。
配列の問題
XMLには配列がありません。繰り返し要素があります。
<users>
<user>Alice</user>
<user>Bob</user>
</users>
これはおそらくこうなるべき:
{"users": {"user": ["Alice", "Bob"]}}
でもこれはどうでしょう:
<users>
<user>Alice</user>
</users>
1つの要素。1つのアイテムの配列ですか、それともただの文字列?異なるコンバーターが異なる決定をします。
一貫性が重要。user が時々配列で時々文字列なら、コードが壊れます。
属性の問題
XMLには属性があります。JSONにはありません。
<product id="123">Widget</product>
一般的な変換戦略:
{"product": {"_id": "123", "_text": "Widget"}}
{"product": {"@id": "123", "#text": "Widget"}}
{"product": {"$": {"id": "123"}, "_": "Widget"}}
すべての規約が異なります。コンバーターが何を生成するか知りましょう。
名前空間の問題
XML名前空間は soap:Envelope のような修飾名を作ります。JSONには名前空間の概念がありません。
コンバーターは:
- プロパティ名にプレフィックスを含める:
"soap:Envelope" - プレフィックスを削除:
"Envelope" - 名前空間処理用のネスト構造を作る
各アプローチにトレードオフがあります。
実践的なコツ
一貫性を保つ。 変換ライブラリを選んでそれを貫きましょう。コンバーターを混ぜると一貫性のない構造を生みます。
配列を強制。 要素が複数インスタンスを持ちえるなら、単一要素でも常に配列を生成するようコンバーターを設定しましょう。
エッジケースをテスト。 サンプルではなく、実際のデータを変換。本番データのエッジケースが驚かせます。
代替を検討。 両端をコントロールしているなら、最初からJSONを使うことを検討。往復変換は情報を失います。
JSONからXMLの課題
逆方向にも問題があります。
配列表現なし。 JSON配列は繰り返し要素になります。それらの要素に名前を付ける必要があります。
{"items": [1, 2, 3]}
何になる?<items><item>1</item>...</items>?「item」はどこから?
数値型。 JSONは数値と文字列を区別。XMLはしません。123 が <value>123</value> になるかも——それは数値か文字列?
変換すべき時
レガシーシステムとの統合。 SOAP APIや古いエンタープライズシステムはXMLを使います。境界で変換。
XMLデータの処理。 JavaScriptはXMLよりJSONをはるかに良く扱います。変換、処理、必要なら変換して戻す。
一度きりのマイグレーション。 XMLベースシステムからJSONベースのものへ移行。
変換すべきでない時
往復要件。 XML → JSON → XMLはしばしば情報を失います。属性、名前空間、順序。
スキーマ検証。 XMLには強力なスキーマ言語(XSD)があります。JSON Schemaはあまり成熟していません。
ドキュメント処理。 XMLの混合コンテンツモデル(埋め込み要素付きテキスト)はJSONにきれいにマップしません。
XMLとJSONはデータを異なる方法で表現。変換には配列、属性、名前空間についての選択が必要。コンバーターの動作を理解し、現実的なデータでテストしましょう。