Reputation: 5588
I have an xml file, I want to open it, edit certain CDATA node with the values from $_POST input and save it as same file, I've read some online documentation and ended up here, someone please suggest a nice way of doing this...
regardsh
Upvotes: 1
Views: 2369
Reputation: 9
You can extend class SimpleXMLElement with simples function to do this
class ExSimpleXMLElement extends SimpleXMLElement {
/**
* Add CDATA text in a node
* @param string $cdata_text The CDATA value to add
*/
private function addCData($cdata_text) {
$node = dom_import_simplexml($this);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($cdata_text));
}
/**
* Create a child with CDATA value
* @param string $name The name of the child element to add.
* @param string $cdata_text The CDATA value of the child element.
*/
public function addChildCData($name, $cdata_text) {
$child = $this->addChild($name);
$child->addCData($cdata_text);
return $child;
}
/**
* Modify a value with CDATA value
* @param string $name The name of the node element to modify.
* @param string $cdata_text The CDATA value of the node element.
*/
public function valueChildCData($name, $cdata_text) {
$name->addCData($cdata_text);
return $name;
}
}
usage:
$xml_string = <<<XML
<root>
<item id="foo"/>
</root>
XML;
$xml5 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
$xml5->valueChildCData($xml5->item, 'mysupertext');
echo $xml5->asXML();
$xml6 = simplexml_load_string($xml_string, 'ExSimpleXMLElement');
$xml6->item->addChildCData('mylittlechild', 'thepunishment');
echo $xml6->asXML();
result:
<?xml version="1.0"?>
<root>
<item id="foo"><![CDATA[mysupertext]]></item>
</root>
<?xml version="1.0"?>
<root>
<item id="foo">
<mylittlechild><![CDATA[thepunishment]]></mylittlechild>
</item>
</root>
Upvotes: 0
Reputation: 429
Since I had the same issue just recently, I wanted to let people also see some code, because the linked examples can only add new CDATA sections, but do not remove the old ones. So "my" solutions is merged from the mentioned code example plus deleting the old CDATA node.
// get DOM node
$node = dom_import_simplexml($mySimpleXmlElement);
// remove existing CDATA ($node->childNodes->item(1) does not seem to work)
foreach($node->childNodes as $child) {
if ($child->nodeType == XML_CDATA_SECTION_NODE) {
$node->removeChild($child);
}
}
// add new CDATA
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($myNewContent));
// print result
echo $xml->asXML();
Upvotes: 1
Reputation: 198204
SimpleXML
does not make CDATA elements accessible by default. You can either tell simplexml to skip them (default) or to read them (see: read cdata from a rss feed). If you read them, they are standard text values, so they get merged with other textnodes.
More control is offered by the Document Object ModelDocs, which offers a DOMCdataSection
which extends from DOMText
, the standard text node model.
Even though this is a different PHP library (DOM vs. SimpleXML), both are compatible to each other. For example a SimpleXMLElement
can be converted into a DOMElement
by using the dom_import_simplexml
function.
If you post some code what you've done so far it should be easy to figure out how to access the CDATA sections you want to modify. Please provide as well some demo XML data so the example is more speaking.
Upvotes: 1
Reputation: 369
I suggest you use this http://www.php.net/manual/en/class.domdocument.php
Upvotes: 0