PHP:如何使用SimpleXMLElement处理<![CDATA [?


97

我注意到在SimpleXMLElement包含这些CDATA标记的文档上使用时,内容始终为NULL。我该如何解决?

另外,很抱歉在这里发送有关XML的垃圾邮件。我一直在尝试使基于XML的脚本可以工作几个小时。

<content><![CDATA[Hello, world!]]></content>

如果您搜索“ SimpleXMLElement cdata”,我会在Google上尝试第一个匹配项,但这没有用。


您如何尝试访问节点值?而且,SimpleXML是必需的吗?
allnightgrocery 2010年

我尝试了在Web上可以找到的所有其他功能(xml2array和所有其他功能),SimpleXML似乎是唯一提供良好结果的功能,除了CDATA无法正常工作。
Angelo 2010年

1
我们在使用DOMDocument(php.net/manual/en/class.domdocument.php)进行大量XML解析。在处理CDATA时效果很好。请简短介绍一下或发布一些代码给我们,以了解您如何使用SimpleXML。
allnightgrocery 2010年

Answers:


182

您可能无法正确访问它。您可以直接输出或将其转换为字符串。(在此示例中,转换是多余的,因为无论如何回声都会自动进行转换)

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
);
echo (string) $content;

// or with parent element:

$foo = simplexml_load_string(
    '<foo><content><![CDATA[Hello, world!]]></content></foo>'
);
echo (string) $foo->content;

您可能会遇到以下好运LIBXML_NOCDATA

$content = simplexml_load_string(
    '<content><![CDATA[Hello, world!]]></content>'
    , null
    , LIBXML_NOCDATA
);

2
不,PHP由于某种原因完全跳过了CDATA。还有其他想法吗?
Angelo 2010年

4
那是个错误。升级PHP / libxml,直到它起作用为止(我对CDATA和SimpleXML从未遇到过任何问题。)否则,您可能希望尝试使用LIBXML_NOCDATA来解决问题。
乔什·戴维斯

5
我知道这是一个旧答案,但是我想强调一下,该答案的第一部分是正确的。当您打印结果时,print_r您确实无法正确访问它。编写您实际想要的代码-可能使用echo或使用(string)强制转换,您会发现内容很好。不要使用LIBXML_NOCDATA无关紧要。
IMSoP

7
@IMSoP添加LIBXML_NOCDATA(并且不进行其他任何更改)是可行的,因此我不确定它是否无关紧要。
2015年

3
@SimonePalazzo XML由各种不同的“节点”组成-例如<anElement>a text node <aChildElement /> <![CDATA a cdata node]]> another text node</anElement>。CDATA和文本节点是不同的类型,SimpleXML会对此进行跟踪,因此您可以取回放入的XML。当您将SimpleXML对象压缩到数组中时,它会丢弃很多信息-CDATA节点,注释,任何不包含元素的元素在当前名称空间(例如<someNSPrefix:someElement />)中,子元素在文本中的位置等。LIBXML_NOCDATA将CDATA节点转换为文本节点,但不修复其余部分。
IMSoP

48

LIBXML_NOCDATA是可选的第三个参数simplexml_load_file()的功能。这将返回XML对象,并将所有CDATA数据转换为字符串。

$xml = simplexml_load_file($this->filename, 'SimpleXMLElement', LIBXML_NOCDATA);
echo "<pre>";
print_r($xml);
echo "</pre>";


修复SimpleXML中的CDATA


LIBXML_NOCDATA是使这项工作对我有效的原因。PHP 5.3.5
Mike_K '17

1
您的答案是一个解释LIBXML_NOCDATA含义的答案,谢谢!
Marcio Mazzucato

14

这帮了我大忙:

echo trim($entry->title);

完美,如果您需要保留cdata(不使用LIBXML_NOCDATA)
maztch 2013年

10

这对我来说是完美的。

$content = simplexml_load_string(
    $raw_xml
    , null
    , LIBXML_NOCDATA
);

0

什么时候使用LIBXML_NOCDATA

我在将XML转换为JSON时添加了问题。

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>");
echo json_encode($xml, true); 
/* prints
   {
     "content": {}
   }
 */

访问SimpleXMLElement对象时,它将获取CDATA:

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>");
echo $xml->content; 
/* prints
   Hello, world!
*/

我使用起来很有意义,LIBXML_NOCDATA因为json_encode我猜想是__toString()等效的,因为它不访问SimpleXMLElement来触发字符串转换功能。

$xml = simplexml_load_string("<foo><content><![CDATA[Hello, world!]]></content></foo>", null, LIBXML_NOCDATA);
echo json_encode($xml);
/*
 {
   "content": "Hello, world!"
 }
*/
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.