myol
myol

Reputation: 9858

DOMDocument saving XML CDATA

I have an xml file with elements in the form of

<TEST id="messageId"><![CDATA[Text I want to manipulate]]></TEST>

I can access the text within the CDATA with the code below

$dom = new DOMDocument;
$dom->Load('/path/to/file.xml');

foreach ($dom->getElementsByTagName('TEST') as $element) {

    $value = $element->nodeValue; //Text I want to manipulate

    // do stuff to $value

    $element->nodeValue = $value; // issue
}

$dom->save('/path/to/different/file.xml');

However when the xml file is saved, the CDATA is missing and I get

<TEST id="messageId">Manipulated text</TEST>

I have read I need to use createCDATASection() but I cannot quite figure out how to use it in this context. If I replace $element->nodeValue = $value with $dom->createCDATASection($value) then I just get the original unmodified XML file saved.

I want to get back to the original format but with the manipulated text

<TEST id="messageId"><![CDATA[Manipulated text]]></TEST>

Upvotes: 1

Views: 849

Answers (2)

cyberbit
cyberbit

Reputation: 1365

You need to append the new CDATA node to the document. From the docs:

This function creates a new instance of class DOMCDATASection. This node will not show up in the document unless it is inserted with (e.g.) DOMNode::appendChild().

Try this code:

foreach ($dom->getElementsByTagName('TEST') as $element) {

    $value = $element->nodeValue;

    // do stuff to $value

    $element->removeChild($element->firstChild);

    $cdata = $dom->createCDATASection($value);
    $element->appendChild($cdata);
}

Upvotes: 1

splash58
splash58

Reputation: 26153

It can be done by next code

foreach ($dom->getElementsByTagName('TEST') as $element) {
    $value = $element->nodeValue; //Text I want to manipulate
    // do stuff to $value
    $new = $dom->createCDATASection($value);
    $element->parentNode->replaceChild($new, $element);
}

 echo $dom->saveXML();

But foreach will break after removing current element. If you want to process some TEST tags, write so:

$tests = $dom->getElementsByTagName('TEST');
$ln = $tests->length;
for($i = 0; $i < $ln; $i++) {
    $element = $tests->item(0);
    $value = $element->nodeValue; //Text I want to manipulate
    // do stuff to $value
    $new = $dom->createCDATASection($value);
    $element->parentNode->replaceChild($new, $element);
}

 echo $dom->saveXML();

Upvotes: 1

Related Questions