12.

【Javaエラー】エンティティ" ... "への参照は';'デリミタで終了する必要があります。

編集
この記事の要点
  • エンティティ "..." への参照は ";" デリミタで終了する必要がありますXML / HTML / JSP で & 文字をエスケープしていない
  • 原因: & はエンティティ参照の開始文字なので、文字として使うには & にエスケープ必須
  • 対処: URL のクエリ区切り、SQL の AND 等で & をそのまま書いている箇所を &
  • JSP / XML の場合は <c:out value="\${url}" /> で自動エスケープが安全

 

エラーの状況

XML エラー
エンティティ "page" への参照は ";" デリミタで終了する必要があります。

# または英語版
The reference to entity "page" must end with the ';' delimiter.

XML パーサがエンティティ参照(&...;)を期待した位置で、& の後に文字が続いて ; で終わらない、というエラー。HTML / JSP / XML / 設定ファイル等で発生します。

原因

<!-- ダメな例 -->
<a href="/search?q=hello&page=2">  <!-- ← &page でエラー -->
<a href="/search?q=A&B">  <!-- ← &B でエラー -->

<p>結果: SELECT * FROM users WHERE active=true & deleted=false</p>  <!-- ← & でエラー -->

XML パーサは & を見つけるとエンティティ参照の始まりと解釈します:

  • &amp;&
  • <<
  • >>
  • &quot;"
  • &#NNN; → 数値文字参照

これらの形式以外は不正と判定されてエラーになります。

対処方法

方法 1: & を & にエスケープ

<!-- 修正 -->
<a href="/search?q=hello&page=2">  <!-- & → & -->
<a href="/search?q=A&B">

<p>SELECT * FROM users WHERE active=true & deleted=false</p>

方法 2: JSP の c:out で自動エスケープ

<!-- JSTL の c:out -->
<c:out value="${url}" />
<!-- 自動的に &, <, > がエスケープされる -->

<!-- EL 式 + c:out -->
<a href="<c:url value='/search'><c:param name='q' value='${query}'/><c:param name='page' value='${page}'/></c:url>">
    検索
</a>

方法 3: CDATA セクション

<![CDATA[
    URL: /search?q=hello&page=2
    SQL: SELECT * WHERE a=1 & b=2
]]>
<!-- CDATA 内は XML パーサが特殊文字として解釈しない -->

JSP での EL 式の自動エスケープ

<!-- JSP 2.0+ -->
<%@ page contentType="text/html;charset=UTF-8" %>

<!-- ${} は標準でエスケープ「されない」-->
<p>${userInput}</p>  <!-- ← XSS 危険、ユーザ入力にはサニタイズ必須 -->

<!-- c:out でエスケープ -->
<p><c:out value="${userInput}" /></p>

<!-- カスタムタグや JSTL fn:escapeXml -->
<p>${fn:escapeXml(userInput)}</p>

HTML の & エスケープ

HTML5 では「& + 既知のエンティティ名 + ;」以外の &そのまま許容されるのでブラウザ表示は壊れません。しかしXML として処理する場面(XHTML / SVG / XML 出力)では厳格にエラーになります。

<!-- HTML5 では許容 (ブラウザは寛容) -->
<a href="/search?q=A&B">  <!-- 動く -->

<!-- XHTML / XML では NG -->
<?xml version="1.0"?>
<a href="/search?q=A&B">  <!-- パースエラー -->

<!-- 安全な書き方 -->
<a href="/search?q=A&B">

サーバサイドでの自動エスケープ

Spring / Thymeleaf

<!-- 標準では自動エスケープ -->
<p th:text="${userInput}">プレースホルダ</p>
<!-- &, <, > が自動的にエスケープされる -->

<!-- エスケープしない場合(信頼できるソースのみ) -->
<p th:utext="${trustedHtml}">プレースホルダ</p>

Laravel Blade

<!-- 自動エスケープ -->
<p>{{ $userInput }}</p>
<!-- &, <, > が自動エスケープ -->

<!-- エスケープなし(XSS 危険、信頼できるソースのみ) -->
<p>{!! $trustedHtml !!}</p>

React / Vue

// React は自動エスケープ
<p>{userInput}</p>  // &, <, > 自動エスケープ
<p dangerouslySetInnerHTML={{ __html: trustedHtml }} />  // 危険

// Vue
<p>{{ userInput }}</p>  // 自動エスケープ
<p v-html="trustedHtml"></p>  // 危険

設定ファイル(XML)でのエスケープ

<!-- web.xml, application.xml, pom.xml 等 -->
<param-value>http://example.com/?a=1&b=2</param-value>

<!-- JNDI 名等 -->
<resource-ref>
    <res-ref-name>jdbc/Pool&1</res-ref-name>
</resource-ref>

<!-- pom.xml のシステム properties -->
<properties>
    <my.url>https://example.com?a=1&b=2</my.url>
</properties>

JSON では & はそのままで OK

JSON は XML ではないので、& のエスケープは不要:

// JSON
{"url": "/search?q=hello&page=2"}  // OK

// ただし JSON を HTML に埋め込む際は HTML 側でエスケープが必要
<script>
const data = {"url": "&"};  // HTML 文脈でこれを書くと <script> タグの解釈が壊れる
</script>

関連エラー

  • The content of elements must consist of well-formed character data: <> をエスケープしていない
  • XML document structures must start and end within the same entity: タグ開閉不一致
  • Premature end of file: XML が途中で終わっている

関連記事

編集
Post Share
子ページ

子ページはありません

同階層のページ
  1. java.lang.NoSuchMethodError
  2. java.lang.ClassCastException: java.util.Date cannot be cast to java.sql.Date
  3. java.lang.UnsupportedClassVersionError
  4. version less than X.X is not supported.
  5. パッケージ~は存在しません
  6. org.apache.jasper.JasperException: ...The jsp:param action must not be...
  7. java.io.FileNotFoundException: ファイル名 (許可がありません)
  8. java.sql.SQLException: Cannot convert value 'YYYY-MM-DD ...' from column n(YYYY-MM-DD ...) to TIMESTAMP.
  9. 警告: この文字は、エンコーディング[文字コード]にマップできません
  10. java.text.ParseException: Unparseable date
  11. Unsupported major.minor version 52.0
  12. エンティティ" ... "への参照は';'デリミタで終了する必要があります。
  13. java.math.BigDecimal cannot be cast to java.lang.String