PHP 生成的 xml 文档中的实体声明(等)


Entity declaration in php generated xml document (  — etc)

这让我发疯,网络上有很多类似的问题,但我找不到正确的解决方案。

我正在用 php 创建一个 xml 文档,作为对 ajax 请求的响应发送。响应将如下所示:

<?xml version="1.0" encoding="iso-8859-1"?>
<response>
  <status>success</status>
  <message>&nbsp;&mdash;</message>
</response>

标签将包含比这更有意义的信息,但正是像这样的实体给我带来了问题。

生成该 xml 的 php 代码如下:

header("Content-Type: text/xml");
$dom = new DOMDocument('1.0', 'iso-8859-1');
$dom->formatOutput = true;
$response_node = $dom->createElement("response");
$dom->appendChild($response_node);
$response_node->appendChild($dom->createElement('status', 'success'));
$response_node->appendChild($dom->createElement('message', "&nbsp;&mdash"));
echo $dom->saveXML();
return;

上面显示的 xml 已成功返回到进行调用的 javascript 函数,但是当它尝试解析 xml 文档时,它会失败。

如果我尝试使用此验证器验证 xml,则会出现以下错误:

此页包含以下错误:

5 行第 15 列的错误:未定义实体"nbsp"

实体&mdash;会导致相同的问题。

我想我可能需要找到一种方法在 xml 中放置这样的东西:

<!ENTITY name "entity_value">

我不确定如何做到这一点,或者这是否是正确的方法。我不是正确的轨道吗?如果是这样,我该怎么做?如果没有,解决这个问题的正确方法是什么?

HTML 实体名称在 XML 中无效,除非如您所指出的<!ENTITY name "...">定义它们。但是数字实体可以解决问题。

尝试更换:

&nbsp; => &#xA0;

&mdash; => &#x2014;

这是解决问题的一种方法,添加一个定义实体的文档类型声明:

$dom = new DOMDocument('1.0', 'iso-8859-1');
$dom->formatOutput = true;
$doctype = DOMImplementation::createDocumentType("html","-//W3C//DTD XHTML 1.1//EN","http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd");
$dom->appendChild($doctype);
$response_node = $dom->createElement("response");
$dom->appendChild($response_node);
$response_node->appendChild($dom->createElement('status', 'success'));
$response_node->appendChild($dom->createElement('message', "&nbsp;&mdash"));
echo $dom->saveXML();
return;

— 不间断空格是完全 UTF-8 有效字符,在 XML 中是允许的。

如果原始消息包含该消息,并且已转换为要在 XML 中显示的实体,请指定要转换 XML 的字符,而不是 HTML 的字符:

PHP 5.4.0+:

$encoded_value = htmlentities($value, ENT_COMPAT | ENT_XML1);

在较旧的 PHP 版本中,默认编码为 ISO-8859-1,因此请指定 UTF-8 作为编码:

$encoded_value = htmlentities($value, ENT_COMPAT | ENT_XML1, 'UTF-8');

注意:您可以使用 html_entity_decode 函数从 mdash 实体获取 — 。