3

PHPDOMクラスで問題が発生しています。

サイトマップスクリプトを作成していますが、$ doc-> saveXML()の出力は次のようになります。

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <url>
        <loc>http://www.somesite.com/servi&#xE7;os/redesign</loc>
    </url>
</root>

また

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <url>
        <loc>http://www.somesite.com/servi&#231;os/redesign</loc>
    </url>
</root>

しかし、私は得ています:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <url>
        <loc>http://www.somesite.com/servi&amp;#xE7;os/redesign</loc>
    </url>
</root>

これは、番号付きエンティティに名前が付けられた置換関数を使用して取得できるクローゼットです。

再現もできました

<?xml version="1.0" ?>
<root>
    <url>
        <loc>http://www.somesite.com/servi&amp;#xE7;os/redesign</loc>
    </url>
</root>

ただし、エンコーディングが指定されていません。

最善の解決策(コードの記述方法)は次のとおりです。

<?php
$myArray = array();
// do some stuff to populate the with URL strings

$doc = new DOMDocument('1.0', 'UTF-8');

// here we modify some property. Maybe is the answer I am looking for...

$urlset = doc->createElement("urlset");
$urlset = $doc->appendChild($urlset);

foreach($myArray as $address) {
    $url = $doc->createElement("url");
    $url = $urlset->appendChild($url);

    $loc = $doc->createElement("loc");
    $loc = $url->appendChild($loc);

    $valueContent = $doc->createTextNode($value);
    $valueContent = $loc->appendChild($address);
}

echo $doc->saveXML();
?>

ノート:

  • サーバー応答ヘッダーには、UTF-8として文字セットが含まれています。
  • PHPスクリプトはUTF-8で保存されます。
  • 読み取られるURLはUTF-8文字列です。
  • 上記のスクリプトには、DOMDocumentコンストラクターのエンコード宣言が含まれており、htmlentities、urlencode、utf8_encodeなどの変換関数は使用されていません。

DOMDocumentプロパティのDOMDocument::$resolveExternalsDOMDocument::$substituteEntitiesの値を変更してみました。組み合わせは機能しませんでした。

はい、DOMDocumentコンストラクターで文字セットを指定せずにすべてのプロセスを作成し、文字列の内容を変数にダンプし、文字列置換関数を使用して非常に単純な文字列置換を行うことができることを知っています。これは機能します。しかし、私はどこで滑っているのか、ネイティブAPIと設定を使用してこれをどのように行うことができるのか、またはこれが可能であるとしても知りたいです。

前もって感謝します。

4

2 に答える 2

1

resolveExternalsおよびsubstituteEntitiesはパーサー機能です。シリアル化には影響しません。

XML情報セットは、次のことをまったく区別しません。

<loc>http://www.somesite.com/serviços/redesign</loc>
<loc>http://www.somesite.com/servi&#xE7;os/redesign</loc>
<loc>http://www.somesite.com/servi&#231;os/redesign</loc>

それらはすべてまったく同じ情報を表し、XMLパーサーはそれらを同一として扱う必要があり、XMLシリアライザーでは通常、どちらを出力するかを選択できません。通常は、テキストノードの値をインクルードするように設定し、シリアライザーが出力に生のUTF-8バイト文字列としてç書き込むようにする必要があります。ç

本当にASCIIのみを含むXMLファイルを生成する必要があるため、直接のような文字を使用できない場合はç、ドキュメントエンコーディングとしてASCIIを使用するようにPHPに指示します。

$s= "serviços"; // or "\xC3\xA7" if you can't input UTF-8 strings directly

$doc = new DOMDocument('1.0', 'US-ASCII');
$doc->appendChild($loc= $doc->createElement('loc'));
$loc->appendChild($doc->createTextNode($s));
echo $doc->saveXML();

結果:

<?xml version="1.0" encoding="US-ASCII"?>
<loc>servi&#231;os</loc>

しかし...そうは言っても、私はまだこれが正しいとは思いません。値はURLのようであり、非ASCII文字は、含まれているXMLでどのようにエンコードされているかに関係なく、URLでは無効です。そのはず:

http://www.somesite.com/servi%C3%A7os/redesign

すなわち。rawurlencode('serviços')

于 2010-05-18T20:38:57.730 に答える
0

createTextNodeに渡す前に、エンティティをデコードします

$valueContent = $doc->createTextNode(html_entity_decode($value, ENT_QUOTES, 'UTF-8'));

&#231; UTF-8ドキュメントの有効なエンティティではありません。したがって、DomDocumentは&を認識し、&amp;としてエンコードします。

于 2010-05-18T20:36:20.433 に答える