5.9 Before and After: Creating New XML Documents

If you want to create a new XML document, you have two choices. Since XML is text, you can always print it yourself using print. The other option is to use DOM.

With DOM you assemble an entire XML document by calling methods in PHP. When you're done, tell DOM to convert your DOM object into XML.

At first, it is much easier to create XML yourself and avoid DOM. Just as extracting information from a DOM object requires multiple steps, adding new nodes to a DOM tree isn't easy. However, using DOM does have some benefits:

  • Your XML is always well-formed and without syntax errors.

  • DOM correctly outputs your document in any one of many different character encodings.

  • You can easily validate your object against a schema.

SimpleXML does not allow you to create XML documents.

5.9.1 Creating an Address Book

The code examples in this section create the address book from Example 5-1 and populate it with the first entry. PHP 4 and DOM

Example 5-19 shows how to create an address book in PHP 4.

Example 5-19. Creating XML with PHP 4 and DOM
// create a new document

$dom = domxml_new_doc('1.0');

$people = $dom->append_child($dom->create_element('address-book'));

$person = $people->append_child($dom->create_element('person'));

$person->set_attribute('id', 1);

$person->append_child($dom->create_comment('Rasmus Lerdorf'));

$e = $person->append_child($dom->create_element('firstname'));


$e = $person->append_child($dom->create_element('lastname'));


$e = $person->append_child($dom->create_element('city'));


$e = $person->append_child($dom->create_element('state'));


$e = $person->append_child($dom->create_element('email'));


echo $dom->dump_mem(true);

This prints:

<?xml version="1.0"?>


  <person id="1">

<!--Rasmus Lerdorf-->








The create_element( ) method creates a new XML element. However, it's not actually attached to the DOM tree: the element is just floating out in the ether, waiting to be placed into a document. The next call, append_child( ), attaches the node to the tree under the object. Similarly, the comment is created using create_comment( ) and is then added to the node.

Therefore, adding new text elements is largely a repetitive process of create and append. For each entry in the address book, both an element and a text node must be created. Those objects are then passed to append_child( ), to insert them into the DOM tree. PHP 5 and DOM

In PHP 5, DOM objects are real PHP objects. This means there are now two ways to interact with DOM. The first way is similar to PHP 4's: you create new nodes by calling methods on a DOM object. However, you can also instantiate nodes as actual PHP objects.

Example 5-20 shows how to make the address book using the PHP 5 DOM syntax.

Example 5-20. Creating XML with PHP 5 and DOM
$dom = new DOMDocument('1.0', 'utf-8');

$people = $dom->appendChild($dom->createElement('address-book'));

$person = $people->appendChild($dom->createElement('person'));

$person->setAttribute('id', 1);

$person->appendChild($dom->createComment('Rasmus Lerdorf'));

$person->appendChild($dom->createElement('firstname', 'Rasmus'));

$person->appendChild($dom->createElement('lastname', 'Lerdorf'));

$person->appendChild($dom->createElement('city', 'Sunnyvale'));

$person->appendChild($dom->createElement('state', 'CA'));

$person->appendChild($dom->createElement('email', 'rasmus@php.net'));

$dom->formatOutput = true; // indent elements

print $dom->saveXML( );

<?xml version="1.0" encoding="utf-8"?>


  <person id="1">

<!--Rasmus Lerdorf-->








The DOMDocument constructor takes two optional arguments: the XML version number and the document encoding. At the time of this writing, most people use XML 1.0 (the W3C released 1.1 on February 4, 2004), and so the default value for this parameter is 1.0. Typical encoding types include UTF-8, UTF-16, and ISO-8859-1 (aka ISO-Latin-1), but you aren't restricted to these three. You can't set the encoding of a DOM document in PHP 4.

Other methods act like they do in PHP 4, but they do not have underscores in their names.

The createElement( ) method has one new feature. If you pass in only one argument, it makes an element with that name. This behavior is similar to how create_element( ) works in PHP 4. However, if you pass in two arguments, the second parameter makes DOMElement create a text element with that string and append it as a child.

DOM supports the full set of XML items: elements, attributes, text nodes, comments, CDATA sections, PIs, and so forth. It also lets you create document fragments, which are identical to DOM objects but don't require the XML stored inside of them to be well-formed. XML, for instance, limits a document to a single root node, but a document fragment can have multiple roots. You might want this setup if you're planning on appending this fragment inside of a XML document, where its layout is valid.

Creating a DOM node of another type, such as a comment, is identical to the earlier example. You just substitute createComment( ) for createElement( ). Table 5-3 lists the all these functions, what they are called in PHP 4, and what they look like in an XML document.

Table 5-3. DOM node-creation functions



PHP 5 method

PHP 5 class




new DOMElement(name)


create_attribute(name, value)

createAttribute(name, value)

new DOMAttribute(name, value)




new DOMText(text)




new DOMComment(comment)





Processing instruction

create_processing_instruction(target, pi)

createProcessingInstruction(target[, pi])

new DOMProcessingInstruction(target[, pi])

Document fragment


createDocumentFragment( )

new DOMDocumentFragment

CDATA sections are similar to text nodes, but inside a CDATA section you don't need to escape entities and other markup characters, because they're treated as literal text.

The object-oriented alternative looks like Example 5-21.

Example 5-21. Creating XML with PHP 5 and DOM using OO
$dom = new DOMDocument('1.0', 'utf-8');

$people = $dom->appendChild(new DOMElement('address-book'));

$person = $people->appendChild(new DOMElement('person'));

$person->appendChild(new DOMAttr('id', 1));

$person->appendChild(new DOMComment('Rasmus Lerdorf'));

$person->appendChild(new DOMElement('firstname', 'Rasmus'));

$person->appendChild(new DOMElement('lastname', 'Lerdorf'));

$person->appendChild(new DOMElement('city', 'Sunnyvale'));

$person->appendChild(new DOMElement('state', 'CA'));

$person->appendChild(new DOMElement('email', 'rasmus@php.net'));

$dom->formatOutput = true; // indent elements

print $dom->saveXML( );

In this version, it's easier to see when you're creating an object and what its type is. The appendChild( ) method is now used even to add new attributes. Instead of calling setAttribute( ), you now append a new DOMAttr object.