在PHP中获取xml子项而不替换html实体

在PHP中获取xml子项而不替换html实体,php,xml,Php,Xml,我有以下代码: <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> $strXml = ' <root> <kid><div>ABC&#8226;&#62;</div></kid> <kid2>DEF</kid2> </root>'; $objXml = new SimpleXMLE

我有以下代码:

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
$strXml = '
<root>
<kid><div>ABC&#8226;&#62;</div></kid>
<kid2>DEF</kid2>
</root>';   

$objXml = new SimpleXMLElement($strXml);
$arrNodes = $objXml->xpath('/root/*');
foreach($arrNodes as $objNode) {
    /* @var $objNode SimpleXMLElement */
    echo $objNode->asXML(); 
}

$strXml='0
ABC&8226>
DEF
';   
$objXml=新的simplexmlement($strXml);
$arrNodes=$objXml->xpath('/root/*');
foreach($arrNodes作为$objNode){
/*@var$objNode simplexmlement*/
echo$objNode->asXML();
}
代码提取根的第一个子项并显示内容。问题是html实体被转换为字符。有没有任何方法可以让代码在不进行任何转换的情况下输出初始XML内容

有没有任何方法可以让代码在不进行任何转换的情况下输出初始XML内容

没有


旁白:你为什么在乎?它们是相同的字符。

SimpleXML/DOMDocument/etc将始终转换这些实体,因为编号的实体不是有效的XML

因此,要么:

  • 史诗般的搜索和替换
  • 或者修复生成XML的任何内容

我觉得这是一种非常奇怪的行为,我在搜索信息时没有任何运气

它似乎影响了所有相关的因素。还值得注意的是,一旦解析XML,字符将作为常规字符存储:

php > print_r($objXml);
SimpleXMLElement Object
(
    [kid] => SimpleXMLElement Object
        (
            [div] => ABC•>
        )

    [kid2] => DEF
)
…当XML转换为文本时,它们被写成实体。我猜所有东西都在使用相同的内部例程转换为文本

如果确实需要此功能,可以创建自己的函数来转义字符,如下所示:

// function to escape some utf8 characters with xml character reference 
function xmlCharEncode($string) {

  $out = '';

  $len = mb_strlen($string, 'UTF-8');

  for ($i = 0; $i < $len; $i++) {

    $char = mb_substr($string, $i, 1, 'UTF-8');

    $convmap = array(
      60,  60, 0, 0xffff, // <
      62,  62, 0, 0xffff, // >
      38,  38, 0, 0xffff, // ampersand
      // you may want to filter quotes or other characters here
      127, 0xffff, 0, 0xffff, // everything after basic latin
    );

    $enc = mb_encode_numericentity($char, $convmap, 'UTF-8');

    $out .= $enc;

  }

  return $out;

}
我真的不相信这是值得的麻烦,但至少你有一个什么样的事情可以做到这一点的想法


顺便说一句,这将适用于您的原始示例。

它们真的被转换了,还是您正在浏览器中查看输出?如果您正在运行代码,请查看页面源代码,我会看到
#&62
输出为
@Michael:你确定吗?我看到了
。我编辑了代码以便您更好地理解,更糟糕的是,有些实体被转换为其名称实体,而bullet被转换为其字符。@ComFreek是的,您是对的,注释中输入了
错误。您关心的是您是否有一个客户端希望最终获得相同的输出,即使技术上是一样的,我真的不会,但那只是我。不管怎样,你都有你的答案。:)数字实体在XML中有效。根据SimpleXML等,它不是。。。不过你在技术上是正确的@IngmarBoddington你能找到关于这个的bug报告或讨论吗?对我来说,这似乎是一种非常奇怪的行为,我根本找不到太多关于它的信息。它似乎影响了所有的PHP XML内容(据我所知)。可能是使用带有新的
ENT\u XML1
标志的
html\u entity\u decode
解决方案:如果这与
filter\u var($value,filter\u flag\u STRIP\u HIGH,filter\u flag\u ENCODE\u HIGH)结合使用
// read and write your xml string

$r = new XMLReader();
$w = new XMLWriter();
$r->xml($strXml);
$w->openMemory();

while($r->read()) {

  switch ($r->nodeType) {

    // write elements, attributes, and text nodes

    case XMLReader::ELEMENT:
      $w->startElement($r->name);
      while ($r->moveToNextAttribute()) {
        echo $w->outputMemory(true);
        $w->writeAttribute($r->name, $r->value);
      }
      break;

    case XMLReader::END_ELEMENT:
      $w->endElement();
      break;

    case XMLReader::TEXT:
      $w->writeRaw(xmlCharEncode($r->value)); // the magic happens here
      break;

  }

  echo $w->outputMemory(true);

}