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

3
这让我感到很烦恼,在网上有很多类似的问题,但我找不到正确的解决方案。
我正在使用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">

我不确定如何做这件事,或者这是否是正确的方法。我是否走错了方向?如果是,我该怎么做呢?如果不是,解决这个问题的正确方法是什么?

3个回答

2

如你所指出的,HTML实体名称在XML中没有定义时是无效的。但是,数字实体可以解决问题。

尝试替换:

&nbsp; => &#xA0;

&mdash; => &#x2014;


我不是手动放置这些实体,它们是在我附加包含这些元素的文本节点时创建的,该文本是从数据库查询的。是否有一种函数可以将命名实体转换为它们的数字等价物? - Matthew
你可以使用 $trans = get_html_translation_table(HTML_ENTITIES) 来获取一个字符到实体的翻译表,然后对于 $trans 中的每个键/值对,像 $table[$value] = '&#' . ord($key) . ';' 这样做来构建你实际需要的表格。但是,一些实体(如 &mdash;)在该表中缺失,因此你可能需要维护一个包含所有可能实体的表格。 - scoffey

2
这是解决问题的一种方法,添加一个定义实体的文档类型声明:
$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;

1

——和不间断空格都是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实体中获取—。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接