PHP 使用 DOMdocument 更新 xml CDATA 字段

PHP updating xml CDATA fields with DOMdocument

我有以下 XML 数据:

<?xml version="1.0" encoding="utf-8"?>
<source>
    <publisher>some-data</publisher>
    <publisherurl>some-data</publisherurl>
    <lastBuildDate>a-date</lastBuildDate>
    <element>
        <sub-element><![CDATA[some-data]]></sub-element>
    </element>
</source>

我正在尝试使用 PHP 的内置 DOMdocument 解析器来更新 sub-element 中的文本。

我试过:

$dom=new DOMDocument();
$dom->load("document.xml");

$ele=$root->getElementsByTagName('element');
foreach ($ele as $e) {
    $e->getElementsByTagName('sub-element')->item(0)->nodeValue = "new val";
}

这种方法可行,但它删除了 CDATA 并仅将其替换为 new-val。我想保留 CDATA 字段,所以我尝试了以下操作:

$dom=new DOMDocument();
$dom->load("document.xml");

$ele=$root->getElementsByTagName('element');
foreach ($ele as $e) {  
    $sub=$e->getElementsByTagName('sub-element');   
    foreach($sub->childNodes as $child) {
        if ($child->nodeType == XML_CDATA_SECTION_NODE) {
            $child->nodeValue = 'new-val';
        }
    }
}

这似乎应该有效,但是 PHP returns 以下 注意

Undefined property: DOMNodeList::$childNodes

感觉我走在正确的道路上,但我就是想不通我做错了什么。有谁知道如何解决?

我的最终目标输出是:

<?xml version="1.0" encoding="utf-8"?>
<source>
    <publisher>some-data</publisher>
    <publisherurl>some-data</publisherurl>
    <lastBuildDate>a-date</lastBuildDate>
    <element>
        <sub-element><![CDATA[new-val]]></sub-element>
    </element>
</source>

您需要与 firstChild

进行比较
$xml = '<?xml version="1.0" encoding="utf-8"?>
<source>
    <publisher>some-data</publisher>
    <publisherurl>some-data</publisherurl>
    <lastBuildDate>a-date</lastBuildDate>
    <element>
        <sub-element><![CDATA[some-data]]></sub-element>
    </element>
    <element>
        <sub-element>some-other-data</sub-element>
    </element>
</source>';

$dom = new DOMDocument();
$dom->loadXML($xml);

$ele=$dom->getElementsByTagName('element');
foreach ($ele as $e) {
    $item = $e->getElementsByTagName('sub-element')->item(0);
    if($item->firstChild->nodeType == XML_CDATA_SECTION_NODE) { //<------
        //it's CDATA do whatever
         $item->firstChild->nodeValue = "new val";
    } else {
        //it's not , do something else
        $item->nodeValue = "new val";
    }
}
echo "<pre>";
print_r(htmlentities($dom->saveXML()));
echo "</pre>";

输出:

<?xml version="1.0" encoding="utf-8"?>
<source>
    <publisher>some-data</publisher>
    <publisherurl>some-data</publisherurl>
    <lastBuildDate>a-date</lastBuildDate>
    <element>
        <sub-element><![CDATA[new val]]></sub-element>
    </element>
    <element>
        <sub-element>new val</sub-element>
    </element>
</source>

PS:如果不用区分CDATA与否,就用firstChild

foreach ($ele as $e) {
    $item = $e->getElementsByTagName('sub-element')->item(0);
    $item->firstChild->nodeValue = "new val";
}