本文へスキップ
jsonbeautifiers
日本語

XMLをJSONに変換

属性・CDATA・実体参照に対応し、対応の取れないタグを正確に指摘します。

XML
JSON

貼り付けたものがブラウザの外に出ることはありません。 connect-src の許可リストにより、これは約束ではなくブラウザによる保証になっています。 自分で確かめる

XMLをJSONに変換します。属性、CDATAセクション、実体参照を適切に処理し、不正なXMLは漠然とではなく正確に報告します。

XMLはJSONが保持できる以上の構造を持つため、この方向の変換には決まった形の情報損失があります。あなたのドキュメントに当てはまるものは、すべて注記で報告します。

本当の問題を名指しするエラー

ブラウザにはXMLパーサーが内蔵されていますが、そのエラー報告はローカライズされたHTMLの断片であり、確実に読み取ることができません。このページは独自のパーサーを使い、診断の質をJSON側と揃えています。

対応の取れないタグ
閉じタグと、それが閉じるはずだった要素の両方を示します。XMLはHTMLと違い、入れ子を厳密に扱います。
閉じられていない要素
ドキュメントが終わった時点で開いたままだったものをすべて列挙します。
2つ目のルート要素
XMLドキュメントのルートはちょうど1つです。2つのファイルを連結したときによく起きます。
HTMLの癖
checkedのような値のない属性や、クォートされていない属性値です。どちらもHTMLとしては正しく、XMLとしてはどちらも不正です。
閉じていないコメントやCDATA
そのセクションが始まった位置で報告します。

JSONで表現できないもの

混在内容
テキストと子要素の両方を持つ要素です。JSONには、テキストを子要素との順序関係を保ったまま持つ手段がありません。そのためテキストは#textという1つのキーにまとめられ、その旨が報告されます。
名前が異なる要素どうしの順序
同名の兄弟要素は配列になり順序を保ちますが、名前の異なる兄弟どうしの相対的な順序は失われます。JSONのオブジェクトのキーには順序がないからです。
名前空間
接頭辞は名前の一部として残り、名前空間宣言そのものは普通の属性になります。
要素1つと複数
要素が1つだけのリストは、要素1つの配列ではなく単一の値になります。これは下流のバグの典型的な原因です。「常に配列にする」を有効にすれば避けられます。

XMLはテキストです。推論を有効にしないかぎりすべて文字列で、有効にした場合でも、float64の往復に耐えない値は文字列のまま残ります。CSVコンバーターと同じ方針であり、理由も同じです。

How to do this in code

コードでの変換。

py Python
import xmltodict, json

data = xmltodict.parse(xml_text)
print(json.dumps(data, indent=2))

# force_list keeps single elements as arrays, which stops the
# classic "sometimes a list, sometimes an object" bug.
data = xmltodict.parse(xml_text, force_list={'item'})
js JavaScript
import { XMLParser } from 'fast-xml-parser';

const parser = new XMLParser({
  ignoreAttributes: false,
  attributeNamePrefix: '@',
  isArray: (name) => name === 'item',
});
const data = parser.parse(xmlText);
sh Shell
# xq, the XML front end to jq
xq . input.xml

# Or with Python, no extra install beyond xmltodict
python -c 'import sys,xmltodict,json; print(json.dumps(xmltodict.parse(sys.stdin.read()), indent=2))' < in.xml

よくある質問

リストのひとつが配列になっていないのはなぜですか?
要素がちょうど1つだったからです。子要素が1つの場合、それを「要素1つのリスト」と区別することはできません。「常に配列にする」を有効にしてください。出力が人間ではなくコードに渡るときは常にそうする価値があり、バグの一群をまるごと取り除けます。
名前空間はどうなりましたか?
接頭辞はキー名の一部として残り、xmlns宣言は普通の属性になります。JSONには名前空間という概念がないため、両者の意味的な結び付きは失われます。
HTMLがパースできないのはなぜですか?
HTMLはXMLではないからです。閉じていない<br>、値のない属性、クォートのない値は、いずれもHTMLとしては正しく、XMLとしてはどれも不正です。HTMLにはHTMLのパーサーが必要で、これではありません。