WebReference.com - Part 2 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (2/4) | WebReference

WebReference.com - Part 2 of Chapter 10 from Professional PHP4 XML, from Wrox Press Ltd (2/4)

To page 1current pageTo page 3To page 4
[previous] [next]

Professional PHP4 XML, Chapter 10: Putting It Together

Using DOM To Modify XML Files

DOM is a good tool to modify XML files since it represents the XML document as an object and has all the methods we need to modify the object. We have methods to add/remove elements, add/remove attributes, move subtrees, and many other tasks. All this would be hard to code using XSLT or SAX.

While DOM eases the process, we have to remember that it consumes a lot of resources and that sometimes, if the documents are really big, it won't perform well enough. Only when the DOM approach is failing due to the size of the XML file, we'll have to look for an XSLT- or SAX-based solution.

For our example we have to write a function to add a product to the XML shopping cart and a function to remove a product from the cart. This is the addProduct() function:

function AddProduct($xml, $id, $name, $desc, $quantity, $unit_price) 
{
    $doc = xmldoc($xml);
    //$doc = domxml_open_mem($xml);
    $root = $doc->document_element();
    $children = $root->child_nodes();
    foreach ($children as $child) {
        if ($child->node_type() == XML_ELEMENT_NODE){
            if ($child->tagname() == "products") {
                $newpro = $doc->create_element("product");
                $newpro->set_attribute("pid", $id);
                $newname = $doc->create_element("name");
                $newname_text = $doc->create_text_node($name);
                $newname->add_child($newname_text);
                $newprice = $doc->create_element("unit_price");
                $newprice_text = $doc->create_text_node($unit_price);
                $newprice->add_child($newprice_text);
                $newdesc = $doc->create_element("desc");
                $newdesc_text = $doc->create_text_node($desc);
                $newdesc->add_child($newdesc_text);
                $newquan = $doc->create_element("quantity");
                $newquan_text = $doc->create_text_node($quantity);
                $newquan->add_child($newquan_text);
                $newpro->add_child($newname);
                $newpro->add_child($newprice);
                $newpro->add_child($newdesc);
                $newpro->add_child($newquan);
                $child->add_child($newpro);
            } 
        }
    }
    $xml = $doc->dump_mem();
    return $xml;
}

Note how the DOM tree is traversed looking for the <products> element, and then the add_child(), create_text_node(), and create_element() methods are used to create a <product> element and its subelements. The set_attribute() method is also used to set an attribute for the <product> element. This mechanism of navigation and insertions is very common when using DOM.

add_child() is an alias of append_child(). append_child() is the proper function to use and works in PHP 4.2.1 and above. So use append_child() instead of add_child() with newer versions of PHP.

To remove all the instances of a product we can use this function:

function RemoveProduct($xml, $id) 
{
    $doc = xmldoc($xml);
    //$doc = domxml_open_mem($xml);
    $root = $doc->root();
    $children = $root->child_nodes();
    foreach ($children as $child) {
        if ($child->node_type() == XML_ELEMENT_NODE){
            if ($child->tagname() == "products") {
                $products = $child->child_nodes();
                foreach ($products as $product) {
                    if ($product->node_type() == XML_ELEMENT_NODE) {
                        // $product_children = $product->child_nodes();
                        $ats = $product->get_attribute("pid");
                        if ($ats == $id) {
                             $product->unlink_node();
                        } 
                    }
                }
            }
        }
    }
    $xml = $doc->dumpmem();  
    return $xml;
}

The function shows how to iterate the DOM tree looking for <product> tags, and how to check for an attribute of an element to see if we did find a product with the ID that we passed to the function.

To be more efficient we may write functions to add/remove elements from the DOM tree, thus parsing the document only once even if we want to add and remove many products. We didn't use this approach on other examples, but it is usually recommended if possible.

DOM is a solid standard for XML modification with methods to add/remove and change nodes. However, it is still not scalable in PHP, and especially scales badly for large XML documents. It also consumes lots of resources.

If you get an errror such as 'undefined function xxx' when trying to test the examples in this chapter, you are probably using an old version of PHP. Examples in this section have been produced from the new DOM extension in PHP 4.2. If you have an earlier version you may want to check the following list of deprecated methods and their replacements in 4.2.

From the PHP documentation:

Deprecated FunctionReplacement Function
DomDocument_dtd()DomDocument_doctype()
DomDocument_root()DomDocument_document_element()
DomDocument_children()DomNode_child_nodes()
DomDocument_imported_node()No replacement
DomNode_add_child()Create a new node with, for example, DomDocument_create_element() and add it with DomNode_append_child()
DomNode_children()DomNode_child_nodes()
DomNode_parent()DomNode_parent_node()
DomNode_new_child()Create a new node with, for example, DomDocument_create_element() and add it with DomNode_append_child()
DomNode_set_content()Create a new node with, for example, DomDocument_create_text_node() and add it with DomNode_append_child().
DomNode_get_content()Content is just a text node and can be accessed with DomNode_child_nodes()
DomNode_set_content()Content is just a text node and can be added with DomNode_append_child()

To page 1current pageTo page 3To page 4
[previous] [next]

Created: August 19, 2002
Revised: August 19, 2002

URL: http://webreference.com/programming/php/php4xml/chap10/2/2.html