Showing posts with label xml. Show all posts
Showing posts with label xml. Show all posts

Searches Through XML with XPath

Friday, March 20, 2009

Directly accessing and traversing through an XML document, is handy when you know the exact format and ordering of the document in question. Often you may be presented with a document that has varying specifications. The data that you want to access might exist under multiple tags. Or you simply may have a large XML document and know that you want only one small piece of data from it.

In these cases, traversing the document tree may not be the best use of your time. Instead, you want to search through the document for the exact item (or items) that you need. This capability is available also through the SimpleXML extension. Within it, you can perform XPath searches. XPath is a standard for performing these kinds of searches through XML.

You perform a search via xpath('searchstring'). The basic format of an XPath search is of the form: "/x/y/z", where x, y, and z are nested XML tags, such as of the form: <x><y><z/></y></x>. Starting the XPath with a "/" as we did means that "x" had to be at the top level. Had that been left off, such as in "x/y/z", it would match that combination of elements at any depth in the XML structure.

Some common XPath queries are explained in the following list; these different queries can be combined in infinite combinations to generate powerful searches:

x Matches any tag named x

x/y Matches any tag named y, directly contained in a tag named x

x/y/.. Similar to the preceding item but actually matches and returns tag x, instead of tag y

x//y Matches any tag named y that is a descendant of a tag named x (any number of levels deep)

x[5] Matches the fifth tag named x

x[last()] Matches the last tag named x

x[@att] Matches any tag named x, with an attribute named att

x[@att="val"] Matches any tag named x, with an attribute named att that has the value "val"

Many more options exist; these are just the most common. To discover more about XPath and all its various options, read the W3C's specification for XPath, found at http://www.w3.org/TR/xpath.

Example Searches of an XML Document

<?php
// Using SimpleXML, read the file into memory:
$xml = simplexml_load_file('contacts.xml');

// Xpath search to find all 'meta' tags no matter what the depth:
$meta = $xml->xpath('//meta');

// Loop over them and output their IDs
foreach ($meta as $m) {
    echo "Meta - {$m['id']}<br />\n";
}

// Find all email tags within a contact tag from the root of the XML document:
$email = $xml->xpath('/contacts/contact/email');

// Loop over them and output the email addreses:
foreach ($email as $e) {
    echo "Email - {$e}<br />\n";
}

// Finally, find any contact who has a cellphone number
$cell = $xml->xpath('contact/phone[@type="cell"]/..');

// Loop over them and output their names:
foreach ($cell as $c) {
    echo "Cell Contact - {$c->name}<br />\n";
}
?>


Hope it helps.

Parsing an XML File to Retrieve Data

Thursday, March 19, 2009

PHP actually provides a number of different ways to access the data from an XML document. The XML, XMLReader, and DOM XML extensions all offer different unique ways in which to navigate through an XML document. Each has its own benefits and drawbacks, and is worth investigating. However, PHP 5 adds another extension, known as SimpleXML. This extension, as it sounds, makes it simple to access XML data and therefore will be the manner this book uses.

SimpleXML at its heart is one of two functions: simplexml_load_string(), which operates on an XML document already saved into a PHP variable, and simplexml_load_file(), which does the same from a file. Upon calling one of these functions SimpleXML returns an object that replicates the XML document. Each XML tag becomes a property of the object, nested accordingly. Perhaps the best way to illustrate this is via an example.

Reading XML Files with SimpleXML

<?php
// Using SimpleXML, read the file into memory:
$xml = simplexml_load_file('contacts.xml');

// Let's print out a formatted version of some of this contact data:
// Start with an ordered list:
echo "<ol>\n";

// Loop over each contact:
foreach ($xml->contact as $c) {
    // Print their name:
    echo '<li>' . $c->name;

    // Now start an Unordered list for their phone numbers:
    echo '<ul>';

    // Loop over every phone number for this person:
    foreach ($c->phone as $p) {
        // Echo out a line including the type of number:
        // The attribute will be accesible as if it were an assoc array
        // entry.  Using the entry itself, will echo it's value.
        echo '<li>', ucfirst($p['type']), ': ', $p, '</li>';
    }

    // Close off the phone list:
    echo "</ul></li>\n";
}
?>


Hope it helps.

Getting XML Data from Server Using AJX

Friday, June 27, 2008

Previously, we use AJAX to receive data from server using the responseText property, it's quite usefull but what if you want to get a complicated data like a bunch of names, addresses, numbers, and many more information in a single request? Sure, you can format your responseText, but why bother if you can use the responseXML property?

Accessing the responseXML will get you a response of HTTP request as XML DOM objects, and this only happen if the XML returned by the server is a valid XML, otherwise you get null.

Here's how we do it.

First, an example of XML file generated by PHP, you can generate more complex with database-driven data, but here's I just a simple plain XML.

<?php
header('Content-type: text/xml');
?>
<students>
 <student year="1999">
  <name>John Smith</name>
  <ssn>23132452</ssn>
 </student>
 <student year="2000">
  <name>Jane Smith</name>
  <ssn>23132453</ssn>
 </student>
</students>
and the javscript code to extract data from XML file.
function getXMLHttp() {
var XMLHttp = null;
if (window.XMLHttpRequest) {
  try {
    XMLHttp = new XMLHttpRequest();
  } catch (e) { }
} else if (window.ActiveXObject) {
  try {
    XMLHttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      XMLHttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (e) { }
  }
}
return XMLHttp;
}

var XMLHttp = getXMLHttp();
XMLHttp.open("GET", "getstudents.php");
XMLHttp.onreadystatechange = function(){
if (XMLHttp.readyState == 4) {
  var xml = XMLHttp.responseXML;
  var student = xml.getElementsByTagName("student")[0];
  var year= student.getAttribute("year");
 var name, ssn;
 for (var i=0; i<student.childNodes.length; i++) {
    if (student.childNodes[i].nodeName == "name") {
      name = student.childNodes[i].firstChild.nodeValue;
    } else if (student.childNodes[i].nodeName == "ssn") {
      ssn= student.childNodes[i].firstChild.nodeValue;
    }
  }
  window.alert(name + " / " + ssn + " / " + year);
}
};
XMLHttp.send(null);
Screenie of the result


I'll write about using documentElement and JSON to do the same thing, but in an easier way, later. For now, I hope the code above suffices.