PHP,SimpleXML的,在CDATA解码实体(PHP, SimpleXML, decoding

2019-07-17 11:16发布

我遇到以下行为:

$xml_string1 = "<person><name><![CDATA[ Someone&#039;s Name ]]></name></person>";
$xml_string2 = "<person><name> Someone&#039;s Name </name></person>";

$person = new SimpleXMLElement($xml_string1);
print (string) $person->name; # Someone&#039;s Name

$person = new SimpleXMLElement($xml_string2);
print (string) $person->name; # Someone's Name

$person = new SimpleXMLElement($xml_string1, LIBXML_NOCDATA);
print (string) $person->name; # Someone&#039;s Name

PHP的文档说NOCDATA“合并[S] CDATA文本节点”。 对我来说,这意味着CDATA将被视为相同的文本节点 - 或者说第三个例子的行为现在是一样的第二个例子。

我没有在XML(这是从外部源饲料)的控制,否则,我只是去掉CDATA标签,因为它无助和废墟我想要的行为。

为什么上面的例子中表现的是它的方式? 有没有什么办法让SimpleXML的处理CDATA节点,它处理文本节点以同样的方式? 什么是“合并CDATA文本节点”,其实这样做,因为我似乎没有被理解这种选择?

我目前的解码我拔出数据之后,但在上面的例子中仍然没有道理给我。

Answer 1:

CDATA节的XML中的目的是封装的文本块“原样”,否则将需要特殊字符(特别是, ><& )进行转义。 包含字符CDATA项&相同含一个普通的文本节点&amp;

如果解析器是提供忽略这一点,并假装一切CDATA节点真的只是文本节点,它会立即尽快打破有人提到的“P&O邮轮” -这&根本不可能是有它自己(而不是作为&amp;&somethingElse;

LIBXML_NOCDATA实际上是用SimpleXML漂亮没用,因为(string)$foo巧妙结合了文本和CDATA节点的任何序列为普通PHP字符串。 (有什么,人们往往没有注意到,因为print_r没有。)这是不是更系统的接入方式,如DOM,在那里你可以操纵文本节点和CDATA节点作为自己的权利的对象一定是真的。

它有效地确实是经过文档,无论在哪里,遇到一个CDATA部分,它需要的内容,它逃脱,并把它放回作为一个普通的文本节点,或“合并”,它与任何文本节点两侧。 表示的文本是相同的,只是存储在不同方式的文档中; 你可以看到区别,如果您导出回XML,如下例:

$xml_string = "<person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person>";

$person = new SimpleXMLElement($xml_string);
echo 'CDATA retained: ', $person->asXML();
// CDATA retained: <?xml version="1.0"?>
// <person><name>Welcome aboard this <![CDATA[P&O Cruises]]> voyage!</name></person>

$person = new SimpleXMLElement($xml_string, LIBXML_NOCDATA);
echo 'CDATA merged: ', $person->asXML();
// CDATA merged: <?xml version="1.0"?>
// <person><name>Welcome aboard this P&amp;O Cruises voyage!</name></person>

如果你解析XML文档包含实际上包含实体CDATA节,你需要采取该字符串和反转义它完全独立于XML的。 一个常见的理由这样做(比知之甚少库懒惰等)是治疗什么的HTML标记的为任何旧的字符串的XML文档中,就像这样:

<Comment>
<SubmittedBy>IMSoP</SubmittedBy>
<Text><![CDATA[I'm <em>really</em> bad at keeping my answers brief <tt>;)</tt>]]></Text>
</Comment>


文章来源: PHP, SimpleXML, decoding entities in CDATA