0

我有一个xml文件:

$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]->asXML()))

  • DOMDocument 可以替代吗?

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

编辑

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

如上所述的行为完全没问题,正如您在答案中看到的那样,必须预料到......

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

4

2 回答 2

2

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

因为那些“特殊”字符实际上是字符的 XML 编码。使用字符串值再次为您提供这些字符。这就是 XML 解析器的用途。

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

嗯,摇摇欲坠。相反,让我建议您相反:XML 对字符串进行编码:

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

DOMDocument 可以替代吗?

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

于 2013-04-18T22:50:48.793 回答
1

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

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

如果出于某种原因您确实需要有关如何在该特定实例中构造 XML 的详细信息,您可以使用更复杂的解析框架,例如 DOM,它将分离testdata&amp;more为一个文本节点(包含“testdata”)、一个实体节点(与名称“amp”)和另一个文本节点(包含“更多”)。

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

于 2013-04-18T19:31:25.310 回答