DevToolBox

XMLパースエラーの原因と直し方 - エラーメッセージ別ガイド

XML を DOMParser や lxml、PHP の SimpleXML に渡すとerror on line 3 at column 15 のようなエラーが返ることがあります。 これらの多くは libxml2 由来の定型メッセージなので、 文言からほぼ一意に原因を特定できます。本記事では頻出5パターンを実例つきで解説します。

This guide decodes the most common XML parse errors emitted by libxml2-based parsers (browser DOMParser, lxml, PHP SimpleXML, xmllint): tag mismatch, unescaped ampersands, multiple root elements, encoding mismatches and undefined namespace prefixes.

TL;DR

XML to JSON Converter

XML を貼り付けるだけで構文チェックと JSON 変換を同時に実行。パースに失敗すればエラー位置がその場で分かります。ブラウザ完結・外部送信なし。

今すぐ試す →

エラーメッセージ早見表 / Quick reference

メッセージ / Message原因 / Cause対処 / Fix
Opening and ending tag mismatch: a line N and b閉じタグ不一致(大文字小文字も区別)タグの対応を修正(2章)
Extra content at the end of the documentルート要素が複数 / 末尾に余分な内容全体を1つの要素で包む(2章)
xmlParseEntityRef: no name& の生書き& にするか CDATA(3章)
Entity 'nbsp' not defined未定義エンティティ(定義済みは5つ)数値文字参照  (3章)
Input is not proper UTF-8, indicate encoding !encoding 宣言と実バイト列の不一致UTF-8 で保存し直す(4章)
Namespace prefix xsi for type on item is not definedxmlns: 宣言の漏れ祖先要素でプレフィックスを宣言(5章)

Find the exact message in this table, then jump to the matching section below for the full fix.

1. error on line N at column M の読み方 / Reading the error position

行・列とも 1始まりです。ブラウザの DOMParser は例外を投げず、<parsererror> 要素を含む文書を返す点に注意してください。

const doc = new DOMParser().parseFromString(xml, "application/xml");
const err = doc.querySelector("parsererror");
if (err) console.log(err.textContent);
// error on line 3 at column 11: Opening and ending tag mismatch: item line 2 and list

コマンドラインなら xmllint --noout file.xml が同じ libxml2 のメッセージを キャレット(^)付きで表示します。列はパーサーがエラーに気づいた位置なので、 閉じタグ不一致のように真の原因が数行前にあるケースでは前方も確認します。

Lines and columns are 1-based. DOMParser never throws; it returns a document containing a parsererror element. The reported column is where the parser noticed the problem, which may be after the actual cause.

2. タグ不一致とルート要素の重複 / Tag mismatch & multiple roots

もっとも多いのが閉じタグの書き間違い・書き忘れです。

<list>
  <item>A
</list>
<!-- parser error : Opening and ending tag mismatch: item line 2 and list -->

メッセージは「item(2行目開始)が list で閉じられた」という意味で、開始タグの行番号が併記されます。XML は大文字小文字を区別するため、<Item>...</item> も同じエラーになります。

ルート要素が2つ以上あると、2つ目の開始位置で次のエラーが出ます。

<a>1</a>
<b>2</b>
<!-- parser error : Extra content at the end of the document -->

XML 文書のルート要素は1つだけです。ログや API レスポンスの断片を連結したときに起きやすく、 全体を <root>...</root> のような要素で包めば解決します。 ルート要素を閉じた後に余分なテキストが残っている場合も同じメッセージです。 構造が深くて目視がつらいときは XML Formatter で 整形すると対応関係が一目で分かります。

"Opening and ending tag mismatch" names both tags and the start-tag line; remember XML is case-sensitive. "Extra content at the end of the document" almost always means a second root element — wrap everything in a single root.

3. & のエスケープ漏れと CDATA / Unescaped & and CDATA

テキスト中に & をそのまま書くと、エンティティ参照の開始と解釈されて失敗します。

<title>Q&A</title>
<!-- parser error : xmlParseEntityRef: no name -->

<title>Q&amp;A</title>  <!-- OK -->

XML に定義済みのエンティティは &amp; &lt; &gt; &quot; &apos;5つだけです。 HTML の感覚で &nbsp; を書くとparser error : Entity 'nbsp' not defined になります。 数値文字参照 &#160; を使ってください。

エスケープしたい文字が多いとき(コードや URL の埋め込み)は CDATA セクションが便利です。 CDATA 内では &< もそのまま書けます。

<script><![CDATA[
  if (a < b && c > 0) { run("a&b"); }
]]></script>

唯一書けないのが終端記号 ]]> そのもので、含めたい場合は]]]]><![CDATA[> のように2つのセクションに分割します。

A raw & triggers "xmlParseEntityRef: no name". XML predefines only five entities, so &nbsp; fails — use &#160;. CDATA sections let you embed code without escaping, except the literal sequence ]]>.

4. 文字コード宣言の不一致 / Encoding mismatch

宣言(または既定)が UTF-8 なのに、実ファイルが Shift_JIS で保存されていると次のエラーになります。

<?xml version="1.0" encoding="UTF-8"?>
<name>あい</name>   ← ファイル自体は Shift_JIS で保存
<!-- parser error : Input is not proper UTF-8, indicate encoding !
     Bytes: 0x82 0xA0 0x82 0xA2 -->

0x82 0xA0 は Shift_JIS の「あ」です。対処は2択で、ファイルを UTF-8 で保存し直す(推奨)か、実体に合わせてencoding="Shift_JIS" と宣言します。XML 宣言がない場合の既定は UTF-8(BOM があればそれに従う)です。

また <?xml ... ?> 宣言の前に空行・空白・出力済みテキストがあるとparser error : XML declaration allowed only at the start of the document が出ます。 テンプレートの先頭の空行や、PHP の閉じタグ後の改行が典型的な犯人です。

"Input is not proper UTF-8, indicate encoding !" means the declared encoding doesn't match the actual bytes — re-save as UTF-8 or fix the declaration. Any whitespace before the XML declaration causes "XML declaration allowed only at the start of the document".

5. 名前空間プレフィックス未定義 / Undefined namespace prefix

xsi:typesoap:Envelope のようなプレフィックスを、xmlns: 宣言なしに使うと名前空間エラーになります。

<item xsi:type="Book"/>
<!-- namespace error : Namespace prefix xsi for type on item is not defined -->

<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <item xsi:type="Book"/>   <!-- OK -->
</root>

宣言はその要素と子孫にだけ有効なので、断片を切り出して別文書に貼ると ルートの宣言が失われてこのエラーになりがちです。プレフィックスを使う要素自身か、 その祖先(通常はルート)に xmlns:プレフィックス="URI" を追加してください。

Namespace prefixes must be declared with xmlns: on the element or an ancestor. Copying a fragment out of its document loses the root declarations and triggers this error.

まとめ / Summary

XML to JSON Converter

直した XML が本当にパースできるか即確認。属性・名前空間付きの XML もそのまま JSON に変換でき、エラーがあれば位置を表示します。

今すぐ試す →

関連ツール / Related tools

関連ガイド / Related guides