我有一个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&more</qkc6b1hh0k9>
</metaData>
EOD;
现在我将它加载到一个simplexmlobject中,稍后我想获得"qkc6b1hh0k9"节点的内部
$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&more
…但是我得到
testdata&more
- 为什么simplexmlobject的__toString()方法将我的转义特殊字符转换为正常字符?我可以取消这个行为吗?
我想出了一个临时解决方案,我觉得很脏,你说呢?
(strip_tags ($ xPathElems[0] ->对asXML ()))
DOMDocument可以是另一种选择吗?
谢谢你对我问题的帮助!
编辑
问题解决了,问题不在simplexml的__toString方法中,它是在稍后使用带有addChild的字符串时出现的
如上所述的行为是完全正常的,正如你在答案中看到的那样…
只有当通过"addChild"将值添加到另一个xml文档时,才会出现问题。由于addChild不会转义& (http://www.php.net/manual/de/simplexmlelement.addchild.php#103587),因此必须手动进行。
为什么simplexmlobject的__toString()方法将我的转义特殊字符转换为正常字符?我可以取消这个行为吗?
因为那些"特殊"字符实际上是字符的XML编码。使用字符串值将再次提供这些字符。这就是XML解析器的作用。
我想出了一个临时解决方案,我认为这是肮脏的,你说呢?
,摇摇欲坠。相反,我建议您使用相反的方法:XML编码字符串:
$var = htmlspecialchars($xPathElems[0]);
var_dump($var);
可以用DOMDocument替代吗?
不,作为SimpleXML,它是一个XML解析器,因此您也可以解码文本。这并不是完全正确的(您可以通过遍历所有子节点并选择字符数据旁边的实体节点来使用DomDocument,但是正如上面的htmlspecialchars()所概述的那样,它要做更多的工作)。
如果您通过任何相同的方法创建XML标记,并将其设置为包含字符串"testdata&more"
,则该字符串将被转义为testdata&more
。因此,唯一合乎逻辑的做法是将该字符串内容提取出来,使转义过程反转,从而得到您输入的文本。
问题是,为什么需要xml转义表示?如果你想要的元素的内容是作者的意图,那么__toString()
是做正确的事情;在XML中表示该字符串的方法不止一种,但通常应该关心的是所表示的数据。
如果出于某种原因,您确实需要XML如何在特定实例中构造的详细信息,您可以使用更复杂的解析框架,例如DOM,它将testdata&more
分离为文本节点(包含"testdata")、实体节点(名称为"amp")和另一个文本节点(包含"more")。
另一方面,如果您只想把它放回另一个XML(或HTML)文档中,那么让SimpleXML正确地进行反转义,并在适当的时候重新转义。