14

DBから取得した値を使用してXMLドキュメントを作成しています。時折、レガシー実装が原因で、適切にエスケープされていない場合(&など)に無効なcharを含む値をプルバックします。

したがって、問題は、CDATAまたはEscapeのどちらにするべきかということです。特定の状況は、一方と他方のどちらに適していますか?

例:

<Email>foo&bar@domain.com</Email>

ここではCDATAに傾倒します。

<Name>Bob & Tom</Name>

私はここから逃げる傾向があります。

毎回盲目的にCDATAを実行することは避けたいのですが、パフォーマンスの観点からは、それが論理的な選択のようです。これは、無効な文字を探すよりも常に高速であり、存在する場合は折り返します。

考え?

4

5 に答える 5

21

CDATAは、人間が読みやすいように、主にIMOで役立ちます。マシンに関する限り、CDATAとエスケープされたテキストの間に長さ以外の違いはありません。エスケープされたバージョンの処理には少し時間がかかるかもしれませんが、アプリケーションがほとんどIOバウンドでない限り、これは重要な要素ではないはずなので、おそらく、私は言います。

人々はXMLを読んでいる可能性がありますか?そうでない場合は、XMLパーサーにその機能を実行させ、CDATAとエスケープされたテキストについて心配する必要はありません。人々がこのXMLを読むのであれば、おそらくCDATAがより良い選択かもしれません。

値がXMLであるXML要素を使用する場合は、この場合、CDATAの方が適している可能性があります。

詳細については、たとえばXML FAQの質問「CDATAマーク付きセクションをいつ使用する必要がありますか? 」を参照してください。

于 2009-06-09T01:04:12.860 に答える
5

私は人々が上記のためにCDATAを使用するのを見てきましたが、これはOKであり、XMLではないもの(JSONやCSSなど)をラップするために使用するので、それを使用するより良い理由です。この問題は、HTMLなどの要素ベースのマークアップを引用するために使用すると混乱が発生します。

人々は期待していません

<![CDATA[<foo>bar</foo>]]>

と同一であるために

&lt;foo&gt;bar&lt;/foo&gt;

XMLシステムに関する限り。

レベルを逃れることの恐怖の例については、RSSタグスープを参照してください。

また、文字シーケンス']]>'がターミネータであるため、ラップされたデータに表示されないことを確認する必要があります。

したがって、読みやすさが最優先であるか、要素以外のマークアップをラップしている場合を除いて、CDATAを避けることをお勧めします。

于 2009-06-09T01:18:52.580 に答える
1

本当の違いはないと思います。エスケープする文字を気にする必要がなく、コンテンツの「]]>」だけを気にする必要があるため、すべてにCDATAを使用することを好みます。これは、CDATAの開口部を分割した場合に許可されます。タグを複数のフラグメントに閉じます。

例(PHP)

<?php

function getXMLContent($content)
{
    if
    (
        (strpos($content, '<') !== false) ||
        (strpos($content, '>') !== false) ||
        (strpos($content, '&') !== false) ||
        (strpos($content, '"') !== false) ||
        (strpos($content, '\'') !== false)
    )
    {
        // If value contains ']]>', we need to break it into multiple CDATA tags
        return "<![CDATA[". str_replace(']]>', ']]]]><![CDATA[>', $content) ."]]>";
    }
    else
    {
        // Value does not contain any special characters which needs to be wrapped / encoded / escaped
        return $content;
    }
}

echo getXMLContent("Hello little world!");
echo PHP_EOL . PHP_EOL;
echo getXMLContent("This < is > a & hard \" test ' for ]]> XML!");

?>

戻り値

Hello little world!

<![CDATA[This < is > a & hard " test ' for ]]]]><![CDATA[> XML!]]>

これを次のようなXML構造に入れると、次のようになります。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<test>
    <![CDATA[This < is > a & hard " test ' for ]]]]><![CDATA[> XML!]]>
</test>

...ファイル(test.xmlなど)に保存し、ブラウザーで開くと、ブラウザー(または他のXMLアプリケーション/パーサー)に正しい出力文字列が表示されることがわかります。

This < is > a & hard " test ' for ]]> XML!
于 2015-10-22T22:07:26.610 に答える
0

これらの条件でCDATAでラップします。疑わしいデータがあり、それらのデータをエスケープしようとしている場合は、そのアプリもエスケープ解除されるため、表示に使用されます。同じデータ要素を繰り返しエスケープします-解析とエスケープの数が増えると、パフォーマンスに影響します。

于 2013-09-25T06:36:05.257 に答える
0

CDATAの方が高速だと思います。最後の文字をスキャンし、最初から最後までコピーを作成して、それを1つのコピーに戻す必要があります。エスケープされたデータの読み取りでは、バッファを使用し、エスケープされた文字をスキャンするときにバッファを追加し、終了したら、バッファを文字列に変換して返します。したがって、エスケープするとより多くのメモリが使用され、余分なコピーを実行する必要があります。おそらく、大量のデータセットと多数のトランザクションの違いに気付くでしょう。したがって、フィールドが小さい場合は、心配する必要はありません。どちらかを使用してください。

于 2016-12-06T11:15:08.800 に答える