将simplexmlelement转换为字符串以获取内部内容但保持htmlspecialchars转义

时间:2013-04-18 11:05:28

标签: php xml simplexml htmlspecialchars object-to-string

我有一个xmlfile:

$xml = <<<EOD
<?xml version="1.0" encoding="utf-8"?>
<metaData xmlns="http://www.test.com/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="test">
<qkc6b1hh0k9>testdata&amp;more</qkc6b1hh0k9>
</metaData>
EOD;

现在我把它加载到一个simplexmlobject中,后来我想得到“qkc6b1hh0k9”-node

的内部
$xmlRootElem = simplexml_load_string( $xml );
$xmlRootElem->registerXPathNamespace( 'xmlns', "http://www.test.com/" );

// ...

$xPathElems = $xmlRootElem->xpath( './'."xmlns:qkc6b1hh0k9" );
$var = (string)($xPathElems[0]);
var_dump($var);

我希望得到字符串

testdata&amp;more

......但我得到了

testdata&more
  • 为什么simplexmlobject的__toString()方法将我的转义特殊字符转换为普通字符?我可以停用此行为吗?
  • 我想出了一个临时解决方案,我觉得它很脏,你说什么?

    (用strip_tags($ xPathElems [0] - &GT; asXML()))

  • 可以将DOMDocument替代吗?

感谢您对我的问题提供任何帮助!

修改

问题解决了,问题不在simplexml的__toString方法中,后来在使用带有addChild的字符串时

如上所述的行为完全没有问题,你可以在答案中看到......

只有在通过“addChild”将值添加到另一个xml文档时才出现问题。 由于addChild不会转义&符号(http://www.php.net/manual/de/simplexmlelement.addchild.php#103587),因此必须手动执行。

2 个答案:

答案 0 :(得分:2)

  

为什么simplexmlobject的__toString()方法将我的转义特殊字符转换为普通字符?我可以停用此行为吗?

因为那些“特殊”字符实际上是字符的XML编码。使用字符串值可以再次逐字显示这些字符。这就是XML解析器的用途。

  

我想出了一个临时解决方案,我认为它很脏,你说什么?

好吧,摇摇欲坠。相反,让我建议你反过来:XML编码字符串:

$var = htmlspecialchars($xPathElems[0]);
var_dump($var);
  

可以将DOMDocument作为替代方案吗?

不,作为SimpleXML,它是一个XML Parser,因此您也可以解码文本。这并不完全正确(你可以通过遍历所有子节点并在字符数据旁边挑选实体节点来使用DomDocument来做到这一点,但是正如 htmlspecialchars()所概述的更多工作上面)。

答案 1 :(得分:1)

如果您通过任何理智方法创建XML标记,并将其设置为包含字符串"testdata&more",则会将其转义为testdata&amp;more。因此,将该字符串内容提取出来反转转义过程以提供您输入的文本是合乎逻辑的。

问题是,为什么要进行XML转义表示?如果您想要作者所期望的元素内容,那么__toString()正在做正确的事情;在XML中表示该字符串的方法不止一种,但是您应该关注的是表示的数据。

如果由于某种原因你真的需要详细说明如何在特定实例中构建XML ,你可以使用更复杂的解析框架,例如DOM,它将testdata&amp;more分成文本节点(包含“testdata”),实体节点(名称为“amp”)和另一个文本节点(包含“more”)。

另一方面,如果你想要的只是将它放回另一个XML(或HTML)文档中,那么让SimpleXML正确地执行unescaping,并在适当的时候重新转义它。