简体   繁体   中英

Edit XML with CDATA using SimpleXMLElement

I've seen a lot of questions with good answers about how to load a XML string with CDATA, or how to write an element with CDATA content, but I haven't been able to find a way to edit a XML that already contains CDATA and keep those previous CDATA after using $xml->asXML() .

Is there a way to edit a XML that already contains CDATA and keep those previous CDATA after using $xml->asXML() ?

Look at this scenario:

<?php
$str_xml = "<myxml><mytag><![CDATA[In this content, 8 > 2 & 1 < 9, and 10 is a 10% of 100. ]]></mytag></myxml>";

try {
    echo "XML with CDATA: \n\n";
    $xml = simplexml_load_string($str_xml, null, LIBXML_NOCDATA);
    echo $xml->asXML() ."\n\n";
} catch(Exception $e){
    echo "XML with CDATA: \n\n";
    echo $e->getMessage() ."\n\n";
}
?>

After running this sample, the output is:

<?xml version="1.0"?>
<myxml><mytag>In this content, 8 &gt; 2 &amp; 1 &lt; 9, and 10 is a 10% of 100. </mytag></myxml>

As you can see, this output XML string has not CDATA tag values anymore. It will not fail to load another simplexml_load_string with this output, but the existing CDATA tags are gone, and also the special characters are replaced by their corresponding html entities.

I need to know if there is a way to read any XML containing any number of CDATA node values, and that after using $xml->asXML() , the output string still contains the previous CDATA tag values.

Thank you for your help.

The XML written out contains no CDATA nodes, because you told SimpleXML to get rid of them when you passed LIBXML_NOCDATA . To keep them, simply don't pass that option!

Here's a live demo of the fixed version , as below:

<?php
$str_xml = "<myxml><mytag><![CDATA[In this content, 8 > 2 & 1 < 9, and 10 is a 10% of 100. ]]></mytag></myxml>";

try {
    echo "XML with CDATA: \n\n";
    $xml = simplexml_load_string($str_xml);
    echo $xml->asXML() ."\n\n";
} catch(Exception $e){
    echo "XML with CDATA: \n\n";
    echo $e->getMessage() ."\n\n";
}

All the answers and comments you have read telling you you need to pass that option in order to use CDATA nodes with SimpleXML are quite simply wrong . The only problem is that the output of print_r , var_dump , etc, doesn't give a full representation of the data accessible by SimpleXML; that doesn't mean it's not there .

To get at the text in your example XML, you just need to cast the element to string (some contexts, such as an echo statement, do this automatically). As in this example :

$xml = simplexml_load_string($str_xml);
$tag_content = (string)$xml->mytag;
echo "Here is the content of the <mytag> node: $tag_content";

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM