2013-04-18 18 views
0

我有一个XMLFILE:投的SimpleXMLElement串得到内的内容,但保留的htmlspecialchars逃脱

$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()方法,把我的逃跑specialChars中正常字符?我可以停用这种行为吗?
  • 我想出了一个临时解决方案,我认为它很脏,你说什么?

    (用strip_tags($ xPathElems [0] - > asXML()))

  • 可能DOM文档是一种替代?

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

编辑

问题解决了,问题并不SimpleXML中的__toString方法,它以后被使用上面是完全以细描述,并且具有以与的addChild

行为字符串时上因为你可以在答案中看到...

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

回答

1

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

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

如果由于某种原因,你真正需要的XML是如何在特定的情况下构建细节,你可以使用更复杂的分析框架,诸如DOM,这将testdata&amp;more分离成文本节点(含“TESTDATA” ),一个实体节点(名称为“amp”)和另一个文本节点(包含“more”)。

另一方面,如果您只想将其放回到另一个XML(或HTML)文档中,请让SimpleXML正确执行转义操作,然后在适当的时候重新转义它。

+0

情况就是这样......数据被放回到另一个xml文档中。但另一个xmldocument中的节点只以“testdata”结束。任何从&符号和之后被剪切 - addChild例如不转换&符号(http://www.php.net/manual/de/simplexmlelement.addchild.php#103587) – Preexo

+1

啊,所以问题不是与'__toString'完全相同,但在目标文档上使用'addChild'。 *任何*数据源可能会给你一个&符号并导致同样的问题。 – IMSoP

+0

耶!似乎他们错过了用“addChild”逃避&符......甚至可能是一个bug ......? – Preexo

2

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

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

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

好吧,摇摇晃晃。相反,让我建议你倒数:XML编码字符串:

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

可能DOM文档是一种替代?

不,因为SimpleXML它是一个XML解析器,因此您也可以解码文本。这并非完全正确(你可以用通过遍历所有的子节点和挑选字符数据旁边的实体节点来完成DomDocument的工作,但是它更像上面提到的htmlspecialchars())那样工作。