3

我对 PHP DOM 类有一些困难。

我正在制作一个站点地图脚本,我需要 $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 序列化程序通常不会让您选择输出哪个。通常,您应该将文本节点的值设置为 includeç并让序列化程序将其写入ç,作为输出中的原始 UTF-8 字节字符串。

如果你真的必须生成一个只包含 ASCII 的 XML 文件,所以你不能ç直接使用类似的字符,那么告诉 PHP 使用 ASCII 作为文档编码:

$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 字符在 URL 中无效,无论它们在包含 XML 中的编码方式如何。它应该是:

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

IE。rawurlencode('serviços').

于 2010-05-18T20:38:57.730 回答
0

在将实体传递给 createTextNode 之前对其进行解码

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

那是因为 ç 不是 UTF-8 文档中的有效实体。所以 DomDocument 看到 & 并将其编码为 &

于 2010-05-18T20:36:20.433 回答