SimpleXML:处理节点值中的CDATA标记

时间:2017-06-22 13:41:15

标签: php simplexml cdata

解析XML文档时,我需要保存<Dest><![CDATA[some text...]]></Dest> 标记。

例如,我有节点:

$dom = simplexml_load_file($path);
foreach($dom->children() as $child) {
 $nodeValue = (string) $child;
}

在xml文件中可能存在没有CDATA的节点。

然后我处理循环中的所有节点:

$nodeValue

因此,当我在上面的例子中处理节点时 - some text... = $nodeValue

但我需要<![CDATA[some text...]]> = <?xml version="1.0" encoding="UTF-8" standalone="yes"?> <Root> <Params> <param>text</param> <anotherParam>text</anotherParam> </Params> <Content> <String> <Source>some another text</Source> <Dest>some another text 2</Dest> </String> <String> <Source>some another text 3</Source> <Dest><![CDATA[some text...]]></Dest> </String> </Content> </Root>

有什么方法可以做到这一点吗?

文件示例:

7 5 6

2 个答案:

答案 0 :(得分:0)

如果您想将CDATA添加到没有CDATA的所有元素,您可以这样做:

$dom = simplexml_load_file($path);
foreach($dom->children() as $child) {
     if(strpos((string) $child,'CDATA')){
         $nodeValue = (string) $child)
     }
     else {
         $nodeValue = "<![CDATA[".((string) $child)."]]>";
     }
 }

你将拥有$nodeValue = '<![CDATA[some text...]]>'

如果您想要有CDATA的元素,您可以这样做:

$dom = simplexml_load_file($path);
foreach($dom->children() as $child) {
     if(strpos((string) $child,'CDATA')){
         $nodeValue = (string) $child;
     }
 }

你将拥有$nodeValue = '<![CDATA[some text...]]>'

如果您想要没有CDATA的元素并添加它,您可以这样做:

$dom = simplexml_load_file($path);
foreach($dom->children() as $child) {
     if(!strpos((string) $child,'CDATA')){
         $notValue ="<![CDATA[".((string) $child)."]]>";
     }
 }

你将拥有$nodeValue = '<![CDATA[some another text 3]]>'

答案 1 :(得分:0)

就像SimpleXML这样的解析器而言,<![CDATA[不是XML元素的文本内容的一部分,它只是该内容序列化的一部分。这里讨论了类似的混淆:PHP, SimpleXML, decoding entities in CDATA

你需要看的是该元素的“内部XML”,这在SimpleXML中很棘手(->asXML()会给你“外部XML”,例如<Dest><![CDATA[some text...]]></Dest>)。

这里最好的选择是使用the DOM,这样您就可以更多地访问文档的详细结构,而不是尝试为您提供内容 ,因此区分“文本节点”和“CDATA节点”。但是,值得仔细检查一下,确实需要这样做,对于99.9%的用例,您不应该关心某人是否向您发送<foo>bar &amp; baz</foo><foo><![CDATA[bar & baz]]></foo>,因为根据定义它们代表相同字符串。