Xml

  • class Cake\Utility\Xml

The Xml class allows you to transform arrays into SimpleXMLElement orDOMDocument objects, and back into arrays again.

Loading XML documents

  • static Cake\Utility\Xml::build($input, array $options = [])

You can load XML-ish data using Xml::build(). Depending on your$options parameter, this method will return a SimpleXMLElement (default)or DOMDocument object. You can use Xml::build() to build XMLobjects from a variety of sources. For example, you can load XML fromstrings:

  1. $text = '<?xml version="1.0" encoding="utf-8"?>
  2. <post>
  3. <id>1</id>
  4. <title>Best post</title>
  5. <body> ... </body>
  6. </post>';
  7. $xml = Xml::build($text);

You can also build Xml objects from local files:

  1. // Local file
  2. $xml = Xml::build('/home/awesome/unicorns.xml');

You can also build Xml objects using an array:

  1. $data = [
  2. 'post' => [
  3. 'id' => 1,
  4. 'title' => 'Best post',
  5. 'body' => ' ... '
  6. ]
  7. ];
  8. $xml = Xml::build($data);

If your input is invalid, the Xml class will throw an exception:

  1. $xmlString = 'What is XML?';
  2. try {
  3. $xmlObject = Xml::build($xmlString); // Here will throw an exception
  4. } catch (\Cake\Utility\Exception\XmlException $e) {
  5. throw new InternalErrorException();
  6. }

Note

DOMDocument andSimpleXML implement different API’s.Be sure to use the correct methods on the object you request from Xml.

Loading HTML documents

HTML documents can be parsed into SimpleXmlElement or DOMDocumentobjects with loadHtml():

  1. $html = Xml::loadHtml($htmlString, ['return' => 'domdocument']);

By default entity loading and huge document parsing are disabled. These modescan be enabled with the loadEntities and parseHuge options respectively.

Transforming a XML String in Array

  • toArray($obj);

Converting XML strings into arrays is simple with the Xml class as well. Bydefault you’ll get a SimpleXml object back:

  1. $xmlString = '<?xml version="1.0"?><root><child>value</child></root>';
  2. $xmlArray = Xml::toArray(Xml::build($xmlString));

If your XML is invalid a Cake\Utility\Exception\XmlException will be raised.

Transforming an Array into a String of XML

  1. $xmlArray = ['root' => ['child' => 'value']];
  2. // You can use Xml::build() too.
  3. $xmlObject = Xml::fromArray($xmlArray, ['format' => 'tags']);
  4. $xmlString = $xmlObject->asXML();

Your array must have only one element in the “top level” and it can not benumeric. If the array is not in this format, Xml will throw an exception.Examples of invalid arrays:

  1. // Top level with numeric key
  2. [
  3. ['key' => 'value']
  4. ];
  5.  
  6. // Multiple keys in top level
  7. [
  8. 'key1' => 'first value',
  9. 'key2' => 'other value'
  10. ];

By default array values will be output as XML tags. If you want to defineattributes or text values you can prefix the keys that are supposed to beattributes with @. For value text, use @ as the key:

  1. $xmlArray = [
  2. 'project' => [
  3. '@id' => 1,
  4. 'name' => 'Name of project, as tag',
  5. '@' => 'Value of project'
  6. ]
  7. ];
  8. $xmlObject = Xml::fromArray($xmlArray);
  9. $xmlString = $xmlObject->asXML();

The content of $xmlString will be:

  1. <?xml version="1.0"?>
  2. <project id="1">Value of project<name>Name of project, as tag</name></project>

Using Namespaces

To use XML Namespaces, create a key in your array with the name xmlns:in a generic namespace or input the prefix xmlns: in a custom namespace. Seethe samples:

  1. $xmlArray = [
  2. 'root' => [
  3. 'xmlns:' => 'https://cakephp.org',
  4. 'child' => 'value'
  5. ]
  6. ];
  7. $xml1 = Xml::fromArray($xmlArray);
  8.  
  9. $xmlArray(
  10. 'root' => [
  11. 'tag' => [
  12. 'xmlns:pref' => 'https://cakephp.org',
  13. 'pref:item' => [
  14. 'item 1',
  15. 'item 2'
  16. ]
  17. ]
  18. ]
  19. );
  20. $xml2 = Xml::fromArray($xmlArray);

The value of $xml1 and $xml2 will be, respectively:

  1. <?xml version="1.0"?>
  2. <root xmlns="https://cakephp.org"><child>value</child>
  3.  
  4. <?xml version="1.0"?>
  5. <root><tag xmlns:pref="https://cakephp.org"><pref:item>item 1</pref:item><pref:item>item 2</pref:item></tag></root>

Creating a Child

After you have created your XML document, you just use the native interfaces foryour document type to add, remove, or manipulate child nodes:

  1. // Using SimpleXML
  2. $myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
  3. $xml = Xml::build($myXmlOriginal);
  4. $xml->root->addChild('young', 'new value');
  5.  
  6. // Using DOMDocument
  7. $myXmlOriginal = '<?xml version="1.0"?><root><child>value</child></root>';
  8. $xml = Xml::build($myXmlOriginal, ['return' => 'domdocument']);
  9. $child = $xml->createElement('young', 'new value');
  10. $xml->firstChild->appendChild($child);

Tip

After manipulating your XML using SimpleXMLElement or DomDocument you canuse Xml::toArray() without a problem.