JSON → XML 変換

ブラウザ上で JSON を整形式 XML に変換します。ルート要素名の指定、XML 宣言の有無、2 スペース・4 スペース・インデントなしの選択に対応しています。

JSON のツリーを安全に要素へ写し取ります。 JSON を貼り付けると整形式の XML が得られます。配列は繰り返し要素に展開され、要素名として使えないキーは自動的に補正されます。宣言とインデントは自由に選べます。

XML 出力

JSON を XML に写すときの考え方

2 つのモデルはそもそも噛み合わない

JSON にはオブジェクト・配列・文字列・数値・真偽値・null の 6 種類の値があり、そのいずれもが型情報を自分で持っています。一方 XML の原始型はテキストただ 1 つで、それ以外はすべて要素と属性で組み立てた構造です。両者を結ぶ公式の対応規則は存在せず、変換ツールごとに挙動が微妙に違うのはそのためです。

ここで採用しているのは、最も一般的で予測しやすい約束です。オブジェクトは要素になり、そのキーが子要素になります。文字列・数値・真偽値はテキスト表現を含む要素になり、null は空要素になります。残るのが配列で、XML には対応物がまったくありません。標準的な回避策は親要素を要素数だけ繰り返すことで、{"item": [1, 2]}<item>1</item><item>2</item> になります。受け側のスキーマが想定していないラッパー要素を勝手に作ることはしません。

すべての JSON キーが要素名になれるわけではない

XML の要素名は NCName の規則に従います。先頭は英字かアンダースコアで、以降は英字・数字・ハイフン・ピリオド・アンダースコアが使えます。空白もスラッシュも不可、先頭の数字も不可、そして大文字小文字を問わず xml で始まる名前は仕様上の予約です。

JSON のキーにはそうした制約がなく、単なる任意の文字列です。実際のデータには "user name""2024""@type" があふれています。これらをそのまま出力すれば、どのパーサーも受け付けない文書になります。そこで不正な文字はアンダースコアに置き換え、数字で始まる名前には先頭にアンダースコアを補います。これは情報が失われる処理なので、要素名が後段で重要なら、変換ツールに推測させるのではなく JSON 側でキーを直してください。

宣言・インデント・変えてよい範囲

UTF-8 の文書では <?xml ... ?> 宣言は省略可能で、無い場合パーサーは UTF-8 とみなします。ファイルとして保存する、HTTP で配信する、厳格な業務システムに渡す——そうした場合は付け、より大きな文書の一部として埋め込む場合は外します。宣言が二重になると致命的なエラーだからです。

より繊細なのがインデントです。JSON と違い、XML では要素内部の空白は内容の一部なので、整形は厳密には文書を変更します。Ada だけを含んでいた要素が、改行・スペース・Ada・改行・スペースを含むようになるからです。多くのスキーマはこれを無視しますが、署名の検証、xml:space="preserve" の区間、空白に敏感な形式はそうではありません。人が読むときはインデントを使い、機械に渡すものは圧縮出力に切り替えてください。

オープンソースに関する注記:バニラ JavaScript で実装。サードパーティライブラリは使用していません。

よくある質問

JSON はどこかにアップロードされますか?
いいえ。ブラウザ内蔵の JSON 関数だけで解析と直列化を行うため、データがサーバーへ送信されることはありません。
JSON の配列はどう表現されますか?
親要素を要素数だけ繰り返します。{"item": [1, 2]} は <item>1</item><item>2</item> になり、多くの XML スキーマが想定する書き方です。
要素名として不正なキーはどうなりますか?
不正な文字はアンダースコアに置換され、数字で始まる場合は先頭にアンダースコアを補います。名前が厳密に必要なら先に JSON 側で直してください。
出力に XML 宣言が無いのはなぜですか?
宣言は任意でチェックボックスで切り替えます。無い場合パーサーは UTF-8 とみなし、他の文書に埋め込むときは必ず外す必要があります。
値が属性として書き出されることはありますか?
ありません。すべての値は要素のテキストになります。属性かどうかは素の JSON からは推測できず、本ツールが持たないスキーマ情報が必要です。
インデントは文書の意味を変えますか?
厳密には変えます。要素内部の空白は内容だからです。多くのスキーマは無視しますが、署名付きや空白に敏感な XML では圧縮出力を使ってください。