How to write CDATA using SimpleXmlElement?
You can also create a helper function for this, if you'd rather not extend SimpleXMLElement:
/**
* Adds a CDATA property to an XML document.
*
* @param string $name
* Name of property that should contain CDATA.
* @param string $value
* Value that should be inserted into a CDATA child.
* @param object $parent
* Element that the CDATA child should be attached too.
*/
$add_cdata = function($name, $value, &$parent) {
$child = $parent->addChild($name);
if ($child !== NULL) {
$child_node = dom_import_simplexml($child);
$child_owner = $child_node->ownerDocument;
$child_node->appendChild($child_owner->createCDATASection($value));
}
return $child;
};
Got it! I adapted the code from this great solution (archived version):
<?php
// http://coffeerings.posterous.com/php-simplexml-and-cdata
class SimpleXMLExtended extends SimpleXMLElement {
public function addCData( $cdata_text ) {
$node = dom_import_simplexml( $this );
$no = $node->ownerDocument;
$node->appendChild( $no->createCDATASection( $cdata_text ) );
}
}
$xmlFile = 'config.xml';
// instead of $xml = new SimpleXMLElement( '<site/>' );
$xml = new SimpleXMLExtended( '<site/>' );
$xml->title = NULL; // VERY IMPORTANT! We need a node where to append
$xml->title->addCData( 'Site Title' );
$xml->title->addAttribute( 'lang', 'en' );
$xml->saveXML( $xmlFile );
?>
XML file generated:
<?xml version="1.0"?>
<site>
<title lang="en"><![CDATA[Site Title]]></title>
</site>
Thank you Petah
Here's my version of this class that has a quick addChildWithCDATA method, based on your answer:
Class SimpleXMLElementExtended extends SimpleXMLElement {
/**
* Adds a child with $value inside CDATA
* @param unknown $name
* @param unknown $value
*/
public function addChildWithCDATA($name, $value = NULL) {
$new_child = $this->addChild($name);
if ($new_child !== NULL) {
$node = dom_import_simplexml($new_child);
$no = $node->ownerDocument;
$node->appendChild($no->createCDATASection($value));
}
return $new_child;
}
}
Simply use it like that:
$node = new SimpleXMLElementExtended();
$node->addChildWithCDATA('title', 'Text that can contain any unsafe XML charachters like & and <>');