XMLの無効な文字とは


229

私は次のような文字列を保持するXMLを使用しています。

<node>This is a string</node>

私は、ノードに渡すのだということを、文字列の一部があります文字が好き&#$、等:

<node>This is a string & so is this</node>

のため、これは無効です&

これらの文字列はそのままにする必要があるため、CDATAでラップすることはできません。CDATAになければXMLノードに配置できない文字のリストを探してみました。

誰かが私をある方向に向けたり、違法なキャラクターのリストを私に提供したりできますか?


4
CDATAを使用しない正当な理由はありますか?
PeterPerháč2009

1
はい、Fatwireという名前のCMSに文字列を渡していますが、データのあるノードをCDATAに含めることはできません。なぜFatwireが機能するのかがわかりません:(
RailsS​​on

@ピーター:私の場合、CDATAをどのように使用できますか?stackoverflow.com/questions/6906705/…–
Radek、

回答:


147

無効な文字は&<および>(および"または'属性内)のみです。

XMLエンティティを使用してエスケープさ&amp;&ます。この場合は、

ただし、実際には、XMLを作成し、この種のものを抽象化して、心配する必要がないツールまたはライブラリーを使用する必要があります。


82
一部の制御文字も使用できません。以下の私の答えを参照してください。
ドルメン

43
実はそうではありません。いくつかの小文字のASCII文字も無効です。Xmlドキュメントに0x03を書き込もうとすると、通常はエラーが発生し、XMLドキュメントに適切にエスケープできた場合、ほとんどのビューアーは無効な文字について文句を言います。エッジケースですが、それは起こります。
Rick Strahl、2012年

16
この答えは間違いです。以下は、0x12の不正な文字を含む私のXML例外です。「System.Xml.XmlException: ''、16進値0x12は無効な文字です」
George

8
それはまた反対の方向にも間違っています。すべての違法な文字が欠落しているだけでなく、違法であると主張する文字は完全に合法ですが、コンテキストでは特別な意味があります。
Jon Hanna

6
XML 1.0には、多くの不正な文字があります。実際、ほとんどの制御文字に文字エンティティを使用しても、解析時にエラーが発生します。
Thayne、2015年

218

OK、次の文字の質問を分離しましょう:

  1. どのXMLドキュメントでもまったく有効ではありません。
  2. エスケープする必要があります。

XMLの無効な文字とは」で@dolmenによって提供された回答は引き続き有効ですが、XML 1.1仕様で更新する必要があります。

1.無効な文字

ここで説明する文字は、XMLドキュメントに挿入できるすべての文字です。

1.1。XML 1.0

使用できる文字のグローバルリストは次のとおりです。

[2] Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

基本的に、制御文字とUnicodeの範囲外の文字は許可されません。これは、たとえば文字エンティティを呼び出すこと&#x3;が禁止されていることも意味します。

1.2。XML 1.1

使用できる文字のグローバルリストは次のとおりです。

[2] Char ::= [#x1-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

[2a] RestrictedChar ::= [#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]

XML勧告のこの改訂では、許可された文字が拡張されたため、制御文字が許可され、Unicode標準の新しい改訂が考慮されていますが、これらの改訂はまだ許可されていません:NUL(x00)xFFFExFFFF ...

ただし、制御文字と未定義のUnicode文字の使用はお勧めしません。

また、すべてのパーサーがこれを常に考慮しているわけではなく、制御文字を含むXMLドキュメントが拒否される場合があることにも注意してください。

2.エスケープする必要がある文字(整形式のドキュメントを取得するため):

<でエスケープする必要があり&lt;、タグの始まりであると想定されるため、エンティティ。

&でエスケープする必要があり&amp;、始まる実体参照であることを想定しているため、実体

>でエスケープする必要があります&gt;エンティティ。これは必須ではありません-コンテキストに依存します-しかし、それを回避することを強くお勧めします。

'でエスケープする必要がある&apos;エンティティ-単一引用符内で定義された属性で必須強く、常にそれをエスケープすることをお勧めします。

"でエスケープする必要がある&quot;エンティティ-二重引用符で定義された属性で必須強く、常にそれをエスケープすることをお勧めします。


171

有効な文字のリストはXML仕様にあります

Char       ::=      #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]  /* any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. */

7
それらは正当な文字です& < > " 'が、特定のコンテキストではエスケープする必要があることに注意してください。
D.Shawley、2011年

7
この文脈での「合法」とは、最終的にデコードされた値が合法であることを意味し、ストリームで合法であることを意味しません。上記のように、いくつかの正当な値はインストリームでエスケープする必要があります。
SilverbackNet 2011

0x1cが不正な文字であるという問題があります... Javaでこれらを回避する方法を探しています...
basZero

有効な文字と無効な文字の概要については、こちらをご覧
Dr.

8
@xamdeこのリストはいいですが、XML要素の開始に使用できる文字のみが表示されます。目下の問題は、一般的にXMLファイルで有効な文字です。どこでも使用できない特定の文字があります。
Jon Senchyna 2014年

59

これは、文字列から無効なXML文字を削除し、新しい有効な文字列を返すC#コードです。

public static string CleanInvalidXmlChars(string text) 
{ 
    // From xml spec valid chars: 
    // #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF]     
    // any Unicode character, excluding the surrogate blocks, FFFE, and FFFF. 
    string re = @"[^\x09\x0A\x0D\x20-\uD7FF\uE000-\uFFFD\u10000-\u10FFFF]"; 
    return Regex.Replace(text, re, ""); 
}

6
Javaの場合、正規表現パターンは同じです。そして、正規表現パターンをパラメーターとして期待するStringクラスのreplaceAllというメソッドを使用できます。:このチェックdocs.oracle.com/javase/6/docs/api/java/lang/...
mathifonseca

2
文字列に無効な文字が含まれています:SUSITARIMO D&#x5; L DARBO SUTARTIESこのコードでは&#x5;は削除されません したがって、xmlドキュメントは初期化に失敗します。
Dainius Kreivys、2015

このパターンを.NET正規表現コンストラクターに入れることはできないと思います。私はそれを認識しないと思う\u10000\u10FFFF、彼らは2 UTF-16必要とする単一文字としてcharインスタンスごとに、かつに従ってドキュメントより、4桁の数字があるではないかもしれません。[\u10000-\u10FFFF]最も可能性が高い[として解析され\u10000-\u10FFFF見ている奇妙なものの、法的です]。
GSerg 2018年

17

事前宣言されている文字は次のとおりです。

& < > " '

詳細については、XMLの特殊文字とは」を参照してください。


違う。これらはすべて無効ではありません。テキストでは常に&と<のみが無効です。
rghome 2018年

7

CDATAブロックを使用してエスケープしたい場合は、potameの回答に加えて。

テキストをCDATAブロックに入れる場合は、エスケープを使用する必要はありません。その場合、次の範囲のすべての文字を使用できます。

可能な文字のグラフィック表現

注:その上、]]>文字シーケンスを使用することはできません。CDATAブロックの最後と一致するからです。

それでも無効な文字(例:制御文字)がある場合は、おそらく何らかのエンコード(例:base64)を使用する方が良いでしょう。


3
CDATAブロック内かどうかに関係なく、一部の文字はXMLで禁止されています。
ドルメン

4
正確には、私が書いたものではありませんか?引用:「次の範囲のすべての文字」。つまり、この特定の範囲の文字のみです。他の文字は使用できません。- 完全に同意します ; しかし、私は反対票を理解していません。-難しい気持ちはありません。
bvdb 2017

6

C#で不要な可能性のあるXML / XHTML文字をエスケープする別の簡単な方法は、次のとおりです。

WebUtility.HtmlEncode(stringWithStrangeChars)

無効な文字
ドルメン

1
彼はHTMLではなくXmlを書いた。
エマヌエーレ

6

C#で不正なXML文字を削除する別の方法は、XmlConvert.IsXmlChar(。NET Framework 4.0以降で利用可能)を使用することです

public static string RemoveInvalidXmlChars(string content)
{
   return new string(content.Where(ch => System.Xml.XmlConvert.IsXmlChar(ch)).ToArray());
}

または、すべての文字がXML有効であることを確認できます。

public static bool CheckValidXmlChars(string content)
{
   return content.All(ch => System.Xml.XmlConvert.IsXmlChar(ch));
}

.Net Fiddle

たとえば、垂直タブ記号(\v)はXMLでは無効であり、UTF-8は有効ですが、XML 1.0は無効であり、多くのライブラリ(libxml2を含む)でもこれを逃して、無効なXMLを警告なしで出力します。


2

要約すると、テキスト内の有効な文字は次のとおりです。

  • タブ、ラインフィード、キャリッジリターン。
  • および以外の すべての非制御文字は有効です。&<
  • >次の場合は無効です]]

XML仕様のセクション2.2および2.4は、詳細な回答を提供します。

キャラクター

有効な文字は、タブ、キャリッジリターン、ラインフィード、およびUnicodeとISO / IEC 10646の有効な文字です。

文字データ

アンパサンド文字(&)と左山かっこ(<)は、マークアップ区切り文字として、またはコメント、処理命令、またはCDATAセクション内で使用される場合を除いて、リテラル形式で表示しないでください。他の場所で必要な場合は、数字参照または文字列 "&"および "<"を使用してエスケープする必要があります。右山かっこ(>)は、文字列 ">"を使用して表すことができ、互換性のために、コンテンツの文字列 "]]>"に出現する場合、 ">"または文字参照を使用してエスケープする必要があります。 stringはCDATAセクションの終わりを示していません。



1
ampersand (&) is escaped to &amp;

double quotes (") are escaped to &quot;

single quotes (') are escaped to &apos; 

less than (<) is escaped to &lt; 

greater than (>) is escaped to &gt;

C#では、System.Security.SecurityElement.EscapeまたはSystem.Net.WebUtility.HtmlEncodeを使用して、これらの不正な文字をエスケープします。

string xml = "<node>it's my \"node\" & i like it 0x12 x09 x0A  0x09 0x0A <node>";
string encodedXml1 = System.Security.SecurityElement.Escape(xml);
string encodedXml2= System.Net.WebUtility.HtmlEncode(xml);


encodedXml1
"&lt;node&gt;it&apos;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"

encodedXml2
"&lt;node&gt;it&#39;s my &quot;node&quot; &amp; i like it 0x12 x09 x0A  0x09 0x0A &lt;node&gt;"

1

Javaの人々のために、Apacheには、XMLエンティティを使用して文字列内の文字をエスケープするために使用できるStringEscapeUtilsヘルパーメソッドescapeXmlを持つユーティリティクラス()があります。


1

Woodstox XMLプロセッサでは、無効な文字は次のコードで分類されます。

if (c == 0) {
    throw new IOException("Invalid null character in text to output");
}
if (c < ' ' || (c >= 0x7F && c <= 0x9F)) {
    String msg = "Invalid white space character (0x" + Integer.toHexString(c) + ") in text to output";
    if (mXml11) {
        msg += " (can only be output using character entity)";
    }
    throw new IOException(msg);
}
if (c > 0x10FFFF) {
    throw new IOException("Illegal unicode character point (0x" + Integer.toHexString(c) + ") to output; max is 0x10FFFF as per RFC");
}
/*
 * Surrogate pair in non-quotable (not text or attribute value) content, and non-unicode encoding (ISO-8859-x,
 * Ascii)?
 */
if (c >= SURR1_FIRST && c <= SURR2_LAST) {
    throw new IOException("Illegal surrogate pair -- can only be output via character entities, which are not allowed in this content");
}
throw new IOException("Invalid XML character (0x"+Integer.toHexString(c)+") in text to output");

ここからソース


-1

誰かがこれを試しましたSystem.Security.SecurityElement.Escape(yourstring)か?これにより、文字列内の無効なXML文字が同等のXML文字に置き換えられます。


-5

XSLの場合(本当に怠惰な日)私は次を使用します:

capture="&amp;(?!amp;)" capturereplace="&amp;amp;"

追跡されていないすべての&記号を翻訳するには、適切なものに。

入力がCDATAにある場合がありますが、XMLを使用するシステムはそれを考慮しません。それはずさんな修正です、用心してください...


8
ずさんな場合、本当にここに投稿する必要がありますか?
ドルメン2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.