PHPBuilder - Using XML: A PHP Developer's Primer Page 2 Page 2



RSS Twitter
Articles

Using XML: A PHP Developer's Primer Page 2 - Page 2

by: Adam Delves
|
July 17, 2008

Saving the XML

You can transform the DOM representation back to the XML string representation using one of the save() and saveXML() methods. The save() function saves the XML to a file with a specified name, whereas the saveXML() function returns a string from part or all of the document.


$xml->save('xml/library.xml'); 
// save the whole file
$categories = $xml->saveXML($XMLCategories); // return a string containing just the categories
To show just how easy it is to port DOM complaint code to another language, here is the same code in Javascript:


Javascript:
function doXML()
{
/* first to create a list of categories */
var categories = Array();
var XMLCategories = xml.getElementsByTagName('categories')[0];

var theCategories = XMLCategories.getElementsByTagName('category');
for (var i = 0; i < theCategories.length; i++) {
/* notice how we get attributes */
var cid = theCategories[i].getAttribute('cid');
categories[cid] = theCategories[i].firstChild.nodeValue;
}


var theBooks = xml.getElementsByTagName('book');
for(var i = 0; i < theBooks.length; i++) {
var book = theBooks[i];

/* find the title */
var title = book.getElementsByTagName('title')[0].firstChild.nodeValue;

/* find the author - for simplicity we assume there is only one */
var author = book.getElementsByTagName('author')[0].firstChild.nodeValue;

/* list categories */
var bookCategories = book.getElementsByTagName('category');

var catList = '';
for(var j = 0; j < bookCategories.length; j++) {
catList += categories[bookCategories[j].firstChild.nodeValue] + ', ';
}

catList = catList.substring(0, catList.length -2);

document.open();
document.write("<h2>" + title + "</h2>");
document.write("<p><b>Author:</b>: " + author + "</p>");
document.write("<p><b>Categories: </b>: " + catList + "</p>");

}
document.close();
}

Simple XML

Simple XML really is simple. It allows access to an XML document, its elements and attributes using object and array access methods. The way this is modeled is simple:

  • Elements - These are represented as single attributes of the SimpleXMLElement object. Where more than one of that element exists as a child of the document or element, each element can be accessed using array index notation.
    $xml->books; // returns the element "books"
    $xml->books->book[0]; // returns the first book inside the books element
  • Attributes - Attributes of elements are accessed and set using associative array notation, where an index corresponds to the attribute name.
    $category['cid']; // returns the value of the cid attribute
  • Element Data - To retrieve the text data contained inside an element, it must be converted to a string explicitly using (string) or output using print or echo. If the element contains more than one text node, they will be concatenated in the order they were found.
    echo ($xml->books->book[0]->title); // displays the title of the first book
Here is the original example converted to use simple XML. To load the XML file, we use the simplexml_load_file() function. This parses the XML file and loads it into a SimpleXMLElement object:

PHP:
<?php
    $xml
= simplexml_load_file('xml/library.xml');

    
/* load a list of categories into an array */
    
$categories = array();
    foreach(
$xml->categories->category as $category) {
        
$categories[(string) $category['cid']] = (string) $category;
    }

    
?>
<html>
    <head>
    <title>XML Library</title>
    </head>
    <body>
    <?php foreach($xml->books->book as $book):
        
/* list categories */
        
$catList = '';
        foreach(
$book->category as $category) {
            
$catList .= $categories[((string) $category)] . ', ';
        }
    
        
$catList = substr($catList, 0, -2); ?>
    
    <div>
        <h2><?php echo($book->title) ?></h2>
        <p><b>Author:</b>: <?php echo($book->author) ?></p>
        <p><b>Categories: </b>: <?php echo($catList) ?></p>
    </div>
    <?php endforeach; ?>
</html>

 

Modifying the XML

Although text data and attribute values can be set using simple XML, new ones cannot be created. However, SimpleXML does provide a way of converting between DomElement objects and SimpleXMLElement objects. I have modified the addCategory() function to show how the simplexml_import_dom() function can be used to add a category and convert the document back to simple XML format:

PHP:

function addCategory(SimpleXMLElement &$sXML, $catID, $catName)
{
    
$xml = new DOMDocument;
    
$xml->loadXML($sXML->asXML());

    
$catName = $xml->createTextNode($catName); // create a node to hold the text
    
$category = $xml->createElement('category'); // create a category element
    
$category->appendChild($catName); // add the text to the category element
    
$category->setAttribute('cid', $catID); // set the category id
    
    
$XMLCategories = $xml->getElementsByTagName('categories')->item(0);
    
$XMLCategories->appendChild($category); // add the new category

    
$sXML = simplexml_import_dom($xml);
    return
$sXML;
}


Similarly, the asXML() function of the SimpleXMLElement object can be used retrieve the XML string and save it back to a file.

xPath
XPath is without a doubt the cherry on top of the XML cake. XPath allows you to use SQL-like queries to search for specific information in an XML document. Both DOM and SimpleXML have built in support for XPath, which, like SQL, can be used to extract just about anything you wish from an XML document.
  • //category - find all occurrences of category anywhere in the document.
  • /library/books - find all occurrences of books which are children of library
  • /library/categories/category[@cid] - find all occurrences of category which are children of library/categories with an attribute named cid
  • /library/categories/category[@att='2'] - find all occurrences of category which are children of library/categories
    with an attribute named cid which have a value of 2
  • /library/books/book[title='Apache 2'] - find all occurrences of book which are children of /library/books and whose title element has a value of Apache 2
This is only the tip of the xPath iceberg. You can create hugely complex queries with xPath to select almost any kind of information from your document. I have modified the sample code once again to show you just how elegant the use of xPath can make it.

PHP:

<?php
    $xml
= simplexml_load_file('xml/library.xml');
?>
<html>
    <head>
    <title>XML Library</title>
    </head>
    <body>
    <?php foreach(((array)$xml->xpath("/library/books/book")) as $book):
        
/* list categories */
        
$catList = '';
        foreach(
$book->category as $category) {
            
/* get the category with this ID */
            
$category = $xml->xpath("/library/categories/category[@cid='$category']");
            
$catList .= (string) $category[0] . ', ';
        }
    
        
$catList = substr($catList, 0, -2); ?>
    
    <div>
        <h2><?php echo($book->title) ?></h2>
        <p><b>Author:</b>: <?php echo($book->author) ?></p>
        <p><b>Categories: </b>: <?php echo($catList) ?></p>
    </div>
    <?php endforeach; ?>
</html>
 


DOM and XPath
Evaluating XPath queries in DOM requires creating a DOMXPath object. The evaluate() function returns an array of DOMElements.
$xPath = new DOMXPath($xml);
$xPath->evaluate("/library/books/book[title='Apache 2']");


Conclusion

Now that we have seen the tools PHP provides us with to interact with XML, we are armed and ready to start delving into some of the applications of XML. In my next article we will be looking at AJAX and show how sites like Google are able to do this (go on, type a search query).

Useful Links



« Previous Page
1

Comment and Contribute

Your comment has been submitted and is pending approval.

Author:
Adam Delves

Comment:



Comment:

(Maximum characters: 1200). You have characters left.