CakePHP Xml utility library triggers DOMDocument warning

Solution 1:

This is a bug in PHPs DOMDocument::createElement() method. Here are two ways to avoid the problem.

Create Text Nodes

Create the textnode separately and append it to the element node.

$dom = new DOMDocument;
$dom
  ->appendChild($dom->createElement('element'))
  ->appendChild($dom->createTextNode('S & T: ERROR'));

var_dump($dom->saveXml());

Output:

string(58) "<?xml version="1.0"?>
<element>S &amp; T: ERROR</element>
"

This is the originally intended way to add text nodes to a DOM. You always create a node (element, text , cdata, ...) and append it to its parent node. You can add more then one node and different kind of nodes to one parent. Like in the following example:

$dom = new DOMDocument;
$p = $dom->appendChild($dom->createElement('p'));
$p->appendChild($dom->createTextNode('Hello '));
$b = $p->appendChild($dom->createElement('b'));
$b->appendChild($dom->createTextNode('World!'));

echo $dom->saveXml();

Output:

<?xml version="1.0"?>
<p>Hello <b>World!</b></p>

Property DOMNode::$textContent

DOM Level 3 introduced a new node property called textContent. It abstracts the content/value of a node depending on the node type. Setting the $textContent of an element node will replace all its child nodes with a single text node. Reading it returns the content of all descendant text nodes.

$dom = new DOMDocument;
$dom
  ->appendChild($dom->createElement('element'))
  ->textContent = 'S & T: ERROR';

var_dump($dom->saveXml());

Solution 2:

This is in fact because the DOMDocument methods wants correct characters to be outputted in html; that is, characters such as & will break content and generate a unterminated entity reference error

just htmlentities() it before using it to create elements:

$dom = new DOMDocument;
$key = 'sub4';
$childValue = htmlentities('S & T: ERROR');
$dom->createElement($key ,$childValue);