diff --git a/source/FluidXml/FluidInsertionHandler.php b/source/FluidXml/FluidInsertionHandler.php index f47fd46..23b5b21 100644 --- a/source/FluidXml/FluidInsertionHandler.php +++ b/source/FluidXml/FluidInsertionHandler.php @@ -269,9 +269,15 @@ protected function insertStringSimple($parent, $k, $v, $fn): array // The user has passed an element name and an element value: // [ 'element' => 'Element content' ] - $el = $this->createElement($k, $v); + $el = $this->createElement($k); $el = $fn($parent, $el); + // createTextNode escapes XML special characters (&, <, >, etc.) + // DOMElement's constructor does not, so we avoid passing value there. + if ($v !== null && $v !== '') { + $el->appendChild($this->dom->createTextNode((string) $v)); + } + return [ $el ]; } diff --git a/specs/FluidXml.php b/specs/FluidXml.php index 6cac1ef..7dd9bca 100644 --- a/specs/FluidXml.php +++ b/specs/FluidXml.php @@ -1181,6 +1181,32 @@ function addchild($parent, $i) assert_equal_xml($xml, $expected); }); + it('should escape XML special characters in text content using the argument syntax', function () { + $xml = new FluidXml(); + $xml->addChild('child1', 'a & b') + ->addChild('parent', true) + ->addChild('child2', 'a < b'); + + $expected = "\n" + . " a & b\n" + . " \n" + . " a < b\n" + . " \n" + . ""; + assert_equal_xml($xml, $expected); + }); + + it('should escape XML special characters in text content using the array syntax', function () { + $xml = new FluidXml(); + $xml->addChild(['child1' => 'Hello & World', 'child2' => 'Tom & Jerry']); + + $expected = "\n" + . " Hello & World\n" + . " Tom & Jerry\n" + . ""; + assert_equal_xml($xml, $expected); + }); + it('should add many children with and without a value', function () { $xml = new FluidXml(); $xml->addChild(['child1', 'child2', 'child3' => 'value3', 'child4' => 'value4'])