【问题标题】:Entity declaration in php generated xml document (  — etc)php 生成的 xml 文档中的实体声明( - 等)
【发布时间】:2011-08-23 17:58:57
【问题描述】:

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

我在 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 文档时,它失败了。

如果我尝试使用 this validator 验证 xml,我会收到以下错误:

此页面包含以下错误:

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

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

我想我可能需要找到一种方法将这样的内容放入 xml:

<!ENTITY name "entity_value">

我不知道该怎么做,或者这是否是正确的方法。我不是正确的轨道吗?如果是这样,我该怎么做?如果不是,解决这个问题的正确方法是什么?

【问题讨论】:

    标签: php html xml dom entity


    【解决方案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 实体中获取 —。

    【讨论】:

      【解决方案2】:

      这是解决问题的一种方法,添加定义实体的 doctype 声明:

      $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;
      

      【讨论】:

        【解决方案3】:

        如您所指出的,如果没有使用&lt;!ENTITY name "..."&gt; 定义它们,HTML 实体名称在 XML 中是无效的。但是数字实体可以解决问题。

        尝试替换:

        &amp;nbsp; => &amp;#xA0;

        &amp;mdash; => &amp;#x2014;

        【讨论】:

        • 我不是手动放置这些实体,它们是在我附加一个包含这些元素的文本节点时创建的,文本是从数据库中查询的。是否有将命名实体转换为其数字等价物的函数?
        • 您可以使用$trans = get_html_translation_table(HTML_ENTITIES) 获取字符到实体的转换表,并对$trans 中的每个键/值执行类似$table[$value] = '&amp;#' . ord($key) . ';'; 的操作来构建您实际需要的表。但是,该表中缺少像 &amp;mdash; 这样的一些实体,因此您可能需要为所有可能的实体维护一个表。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        • 2014-08-03
        • 2011-12-30
        • 1970-01-01
        相关资源
        最近更新 更多