12.2.1. ProblemYou want to generate XML but want to do it in an organized way instead of using print and loops. 12.2.2. SolutionUse the DOM extension to create a DOMDocument object. After building up the document, call DOMDocument::save( ) or DOMDocument::saveXML( ) to generate a well-formed XML document: <?php // create a new document $dom = new DOMDocument('1.0'); // create the root element, <book>, and append it to the document $book = $dom->appendChild($dom->createElement('book')); // create the title element and append it to $book $title = $book->appendChild($dom->createElement('title')); // set the text and the cover attribute for $title $title->appendChild($dom->createTextNode('PHP Cookbook')); $title->setAttribute('cover', 'soft'); // create and append author elements to $book $sklar = $book->appendChild($dom->createElement('author')); // create and append the text for each element $sklar->appendChild($dom->createTextNode('Sklar')); $trachtenberg = $book->appendChild($dom->createElement('author')); $trachtenberg->appendChild($dom->createTextNode('Trachtenberg')); // print a nicely formatted version of the DOM document as XML $dom->formatOutput = true; echo $dom->saveXML(); ?> <?xml version="1.0"?> <book> <title cover="soft">PHP Cookbook</title> <author>Sklar</author> <author>Trachtenberg</author> </book> 12.2.3. DiscussionThe DOM methods follow a pattern. You create an object as either an element or a text node, add and set any attributes you want, and then append it to the tree in the spot it belongs. Before creating elements, create a new document, passing the XML version as the sole argument: $dom = new DOMDocument('1.0'); Now create new elements belonging to the document. Despite being associated with a specific document, nodes don't join the document tree until appended: $book_element = $dom->createElement('book'); $book = $dom->appendChild($book_element); Here a new book element is created and assigned to the object $book_element. To create the document root, append $book_element as a child of the $dom document. The result, $book, refers to the specific element and its location within the DOM object. All nodes are created by calling a method on $dom. Once a node is created, it can be appended to any element in the tree. The element from which we call the appendChild( ) method determines the location in the tree where the node is placed. In the previous case, $book_element is appended to $dom. The element appended to $dom is the top-level node, or the root node. You can also append a new child element to $book. Since $book is a child of $dom, the new element is, by extension, a grandchild of $dom: $title_element = $dom->createElement('title'); $title = $book->appendChild($title_element); By calling $book->appendChild( ), this code places the $title_element element under the $book element. To add the text inside the <title></title> tags, create a text node using createTextNode( ) and append it to $title: $text_node = $dom->createTextNode('PHP Cookbook'); $title->appendChild($text_node); Since $title is already added to the document, there's no need to re-append it to $book. The order in which you append children to nodes isn't important. The following four lines, which first append the text node to $title_element and then to $book, are equivalent to the previous code: $title_element = $dom->createElement('title'); $text_node = $dom->createTextNode('PHP Cookbook'); $title_element->appendChild($text_node); $book->appendChild($title_element); To add an attribute, call setAttribute( ) upon a node, passing the attribute name and value as arguments: $title->setAttribute('cover', 'soft'); If you print the title element now, it looks like this: <title cover="soft">PHP Cookbook</title> Once you're finished, you can output the document as a string or to a file: // put the string representation of the XML document in $books $books = $dom->saveXML(); // write the XML document to books.xml $dom->save('books.xml'); By default, these methods generate XML output in one long line without any whitespace, including indentations and line breaks. To fix this, set the formatOutput attribute of your DOMDocument to true: // print a nicely formatted version of the DOM document as XML $dom->formatOutput = true; This causes the DOM extension to generate XML like this: <?xml version="1.0"?> <book> <title cover="soft">PHP Cookbook</title> </book> 12.2.4. See AlsoRecipe 12.1 for writing XML without DOM; Recipe 12.4 for parsing XML with DOM; documentation on DOMDocument at http://www.php.net/function.dom-domdocument-construct.php and the DOM functions in general at http://www.php.net/dom; more information about the underlying libxml2 C library at http://xmlsoft.org/. |