138

]]>XML ドキュメントの CDATA セクション内でCDATA エンド トークン ( ) をエスケープする方法があるかどうか疑問に思っていました。または、より一般的には、CDATA 内で使用するためのエスケープ シーケンスがある場合 (ただし、存在する場合は、begin または end トークンをエスケープすることだけがおそらく意味があると思います)。

基本的に、CDATA に開始トークンまたは終了トークンを埋め込んで、それを解釈せずに別の文字列として扱うようにパーサーに指示できますか。

おそらく、xml 構造またはコードをリファクタリングしようとしている場合は、単にリファクタリングする必要がありますが、私は過去 3 年ほど xml を日常的に使用してきましたが、この問題が発生したことはありません。それが可能かどうか疑問に思っていました。単なる好奇心から。

編集:

htmlエンコーディングを使用する以外...

4

9 に答える 9

175

を隠すには、データを細かく分割する必要があります]]>

ここにすべてがあります:

<![CDATA[]]]]><![CDATA[>]]>

最初<![CDATA[]]]]>のものは]]. 2 つ目<![CDATA[>]]>>.

于 2008-10-21T22:27:56.540 に答える
148

明らかに、この質問は純粋に学術的なものです。幸いなことに、それには非常に明確な答えがあります。

CDATA 終了シーケンスをエスケープすることはできません。XML仕様のプロダクション ルール 20は非常に明確です。

[20]    CData      ::=      (Char* - (Char* ']]>' Char*))

編集: この製品ルールは、文字通り、「CData セクションには、必要なものは何でも含めることができますが、シーケンス ']]>' を含むことができます。例外はありません。」を意味します。

EDIT2:同じセクションにも次のように書かれています:

CDATA セクション内では、CDEnd 文字列のみがマークアップとして認識されるため、左山かっことアンパサンドがリテラル形式で発生する可能性があります。&lt;" " および " "を使用してエスケープする必要はありません (また、エスケープすることもできません) &amp;。CDATA セクションはネストできません。

つまり、エンティティ参照、マークアップ、またはその他の形式の解釈された構文を使用することはできません。CDATA セクション内の唯一の解析済みテキストは]]>であり、セクションを終了します。

したがって、]]>CDATA セクション内でエスケープすることはできません。

EDIT3:同じセクションにも次のように書かれています:

2.7 CDATAセクション

[定義: CDATA セクションは、文字データが発生する場所であればどこでも発生する可能性があります。それらは、そうでなければマークアップとして認識される文字を含むテキストのブロックをエスケープするために使用されます。CDATA セクションは文字列 "<![CDATA[" で始まり、文字列 "]]>" で終わります:]

次に、単一の CDATA セクションの代わりに複数の隣接する CDATA セクションを含む、文字データが発生する可能性のある場所ならどこにでも CDATA セクションが存在する可能性があります。これにより、]]>トークンを分割し、その 2 つの部分を隣接する CDATA セクションに入れることができます。

元:

<![CDATA[Certain tokens like ]]> can be difficult and <invalid>]]> 

次のように書く必要があります

<![CDATA[Certain tokens like ]]]]><![CDATA[> can be difficult and <valid>]]> 
于 2008-10-21T22:31:04.210 に答える
17

エスケープはしませんが、の前に挿入して後]]>をエスケープします。これは、C / Java / PHP / Perl文字列の場合と同じように考えてください。ただし、aの前後にのみ必要です。>]]]]><![CDATA[>\>]]

ところで、

S.Lottの答えはこれと同じですが、言い方が異なります。

于 2011-03-30T20:24:37.557 に答える
7

S. Lott の答えは正しいです。終了タグをエンコードせず、複数の CDATA セクションに分割します。

現実世界でこの問題に遭遇する方法: XML エディタを使用して、コンテンツ管理システムにフィードされる XML ドキュメントを作成し、CDATA セクションに関する記事を書いてみてください。コード サンプルを CDATA セクションに埋め込む通常のトリックは、ここでは失敗します。私がこれをどのように学んだか想像できます。

しかし、ほとんどの状況では、これに遭遇することはありません。その理由は次のとおりです。XML ドキュメントのテキストを XML 要素のコンテンツとして格納 (たとえば) したい場合は、おそらく DOM メソッドを使用します。たとえば、次のようになります。

XmlElement elm = doc.CreateElement("foo");
elm.InnerText = "<[CDATA[[Is this a problem?]]>";

また、DOM は < と > を非常に合理的にエスケープします。つまり、ドキュメントに誤って CDATA セクションを埋め込むことはありません。

ああ、これは興味深いです:

XmlDocument doc = new XmlDocument();

XmlElement elm = doc.CreateElement("doc");
doc.AppendChild(elm);

string data = "<![[CDATA[This is an embedded CDATA section]]>";
XmlCDataSection cdata = doc.CreateCDataSection(data);
elm.AppendChild(cdata);

これはおそらく .NET DOM の特異性によるものですが、例外はスローされません。ここで例外がスローされます。

Console.Write(doc.OuterXml);

内部で起こっていることは、XmlDocument が XmlWriter を使用して出力を生成し、XmlWriter が書き込み時に整形式かどうかをチェックしていることだと思います。

于 2008-10-22T00:00:47.087 に答える
3

]]>エスケープする必要がある別のケースを次に示します。XML ドキュメントの CDATA ブロック内に完全に有効な HTML ドキュメントを保存する必要があり、HTML ソースに独自の CDATA ブロックがあるとします。例えば:

<htmlSource><![CDATA[ 
    ... html ...
    <script type="text/javascript">
        /* <![CDATA[ */
        -- some working javascript --
        /* ]]> */
    </script>
    ... html ...
]]></htmlSource>

コメント付きの CDATA サフィックスを次のように変更する必要があります。

        /* ]]]]><![CDATA[> *//

XML パーサーは JavaScript コメント ブロックの処理方法を認識できないためです。

于 2012-06-08T05:34:38.803 に答える
1

PHP の場合:'<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'

于 2013-03-21T09:49:09.390 に答える