XMLフォーマッター
XMLをフォーマットして構文ハイライト付きで見やすく表示
XML入力
フォーマットされたXML
XMLフォーマットとは?
XMLフォーマット(XMLプリティプリントやXML整形とも呼ばれます)とは、XMLドキュメントに一貫したインデントと改行を追加し、階層構造を視覚的に分かりやすくするプロセスです。API、設定ジェネレーター、シリアライザーから出力される生のXMLは、タグ間に空白を持たない1行形式で提供されることがよくあります。XMLフォーマッターはそのドキュメントをツリーとして解析し、予測可能な間隔で再シリアライズします。
XML 1.0仕様(W3C勧告、第5版)は厳格な文法を定義しています。すべての開始タグには対応する終了タグまたは自己終了タグが必要で、属性値はクォートで囲まれなければならず、5つの文字(<、>、&、"、')はエンティティエスケープが必要です。フォーマッターはこれらのルールを守りながら、ドキュメントの情報セット(infoset)を変えない「意味のない空白」のみを挿入する必要があります。
フォーマットされたXMLはコードレビューで読みやすく、バージョン管理での差分確認が容易で、サービスが予期しないデータを返した際のデバッグも簡単です。フォーマット操作自体は可逆的です。ドキュメントの論理的な内容は変わらず、見た目のみが変化します。git diffやプルリクエストのレビュープラットフォームは変更された行のみを表示するため、一貫したインデントのXMLは実際の変更のみを差分に反映し、フォーマット変更のノイズを排除します。
<catalog><book id="bk101"><author>Gambardella, Matthew</author><title>XML Developer's Guide</title><genre>Computer</genre><price>44.95</price><publish_date>2000-10-01</publish_date></book><book id="bk102"><author>Ralls, Kim</author><title>Midnight Rain</title><genre>Fantasy</genre><price>5.95</price><publish_date>2000-12-16</publish_date></book></catalog>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
<title>XML Developer's Guide</title>
<genre>Computer</genre>
<price>44.95</price>
<publish_date>2000-10-01</publish_date>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
<title>Midnight Rain</title>
<genre>Fantasy</genre>
<price>5.95</price>
<publish_date>2000-12-16</publish_date>
</book>
</catalog>オンラインXMLフォーマッターを使う理由
XMLを手動でフォーマットするのは、特に深いネストや混在した名前空間を持つドキュメントでは、ミスが多く時間もかかります。ブラウザベースのフォーマッターはファイルサイズに関わらず1秒以内に結果を提供します。
XMLフォーマッターの使用例
XML定義済みエンティティ参照
XMLは構文のために5つの文字を予約しています。これらの文字がテキストコンテンツや属性値として現れる場合、定義済みエンティティ参照に置き換える必要があります。正しいフォーマッターはプリティプリント中にこれらのエンティティを保持します。
| 文字 | XMLでの役割 | エンティティ |
|---|---|---|
| < | Start of tag | < |
| > | End of tag | > |
| & | Start of entity | & |
| " | Attribute delimiter | " |
| ' | Attribute delimiter | ' |
XMLインデントスタイルの比較
XMLインデントに単一の標準はありません。選択はチームの規約とパイプラインのツールに依存します。以下は最もよく使われる3つのスタイルです。
コード例:XMLをプログラムでフォーマット
スクリプトやビルドプロセスの中でXMLをフォーマットする必要がある場合、主要な言語には組み込みまたは標準ライブラリのオプションがあります。以下はそのままコピーして使える実用的なサンプルです。
const raw = '<root><item>hello</item></root>'
const parser = new DOMParser()
const doc = parser.parseFromString(raw, 'application/xml')
const serializer = new XMLSerializer()
const xml = serializer.serializeToString(doc)
// Indent with XSLT (browser-native approach)
const xslt = new DOMParser().parseFromString(`
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="node()|@*">
<xsl:copy><xsl:apply-templates select="node()|@*"/></xsl:copy>
</xsl:template>
</xsl:stylesheet>`, 'application/xml')
const proc = new XSLTProcessor()
proc.importStylesheet(xslt)
const formatted = proc.transformToDocument(doc)
console.log(new XMLSerializer().serializeToString(formatted))
// → <root>\n <item>hello</item>\n</root>import xml.dom.minidom raw = '<root><item>hello</item><item>world</item></root>' dom = xml.dom.minidom.parseString(raw) print(dom.toprettyxml(indent=' ')) # → <?xml version="1.0" ?> # → <root> # → <item>hello</item> # → <item>world</item> # → </root> # With lxml (handles namespaces, XSD, large files) from lxml import etree tree = etree.fromstring(raw.encode()) print(etree.tostring(tree, pretty_print=True).decode())
package main
import (
"encoding/xml"
"fmt"
"strings"
)
func formatXML(raw string) (string, error) {
decoder := xml.NewDecoder(strings.NewReader(raw))
var out strings.Builder
encoder := xml.NewEncoder(&out)
encoder.Indent("", " ")
for {
tok, err := decoder.Token()
if err != nil {
break
}
encoder.EncodeToken(tok)
}
encoder.Flush()
return out.String(), nil
}
// formatXML("<a><b>1</b></a>") → "<a>\n <b>1</b>\n</a>"# Format XML file with xmllint (part of libxml2, pre-installed on macOS/Linux) xmllint --format input.xml > formatted.xml # Format from stdin echo '<a><b>1</b></a>' | xmllint --format - # → <?xml version="1.0"?> # → <a> # → <b>1</b> # → </a> # Validate and format at the same time xmllint --format --schema schema.xsd input.xml