【问题标题】:PHP updating xml CDATA fields with DOMdocumentPHP 使用 DOMdocument 更新 xml CDATA 字段
【发布时间】:2018-01-24 20:54:20
【问题描述】:

我有以下 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 返回以下 通知

未定义属性: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>

【问题讨论】:

    标签: php xml domdocument cdata


    【解决方案1】:

    你需要和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";
    }
    

    【讨论】:

    • 我正在寻找的输出是这样的:&lt;sub-element&gt;&lt;![CDATA[new val]]&gt;&lt;/sub-element&gt; 我该怎么做?
    • $item-&gt;firstChild-&gt;nodeValue = "new val";已编辑,看看
    • 或者如果可以忽略比较并一直使用firstChild
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-06
    • 1970-01-01
    相关资源
    最近更新 更多