How to use XPath and Sorting in XML
In the first article, I showed you how to get quick results with XML, XSL, and ASP. I also introduced a short paragraph about XPath. In this article, I will show you how you can use this combination with a very easy and understandable code to sort data. As sorting is a very important task that needs to be implemented in nearly every form, simplifying its implementation will save you precious development time in your projects. As opposed to the hand-crafted solutions that one needed to use in the past, XPath enables you to write robust, self-documented, and easy to understand sorting code with a very short development cycle.
XPath is one of the useful features when using XML elements. Its main purpose is to retrieve specific nodes from an XML document. As was already mentioned in my first article, it works like the SQL "select" statement for databases. As the XPath name already suggests, it uses path expressions to identify nodes in an XML document, which is similar to the path expressions of your file system:
This expression will identify the file xpath.txt. We build XPath expressions similar to this. In both cases, the root node is identified by a slash ( / ).
We will use the following XML document to describe the various types of the XPath expression:
<?xml version="1.0" encoding="ISO-8859-1"?> <PersonList> <Person> <Name>Sonu Kapoor</Name> <Age>24</Age> <Gender>M</Gender> <PostalCode>54879</PostalCode> </Person> <Person> <Name>Jasmin</Name> <Age>28</Age> <Gender>F</Gender> <PostalCode>78745</PostalCode> </Person> </PersonList>
The following XPath expression will be used to select all names in the PersonList/Person element.
If we want to select a specific person, we can use the following:
Except for the equal operator ( = ), we can also make use of the greater than ( > ) and less than ( < ) operators. The combinations <=, >= and != (not equal) also are acceptable.
The following expression will retrieve all persons who are older than 18 years old.
Strings are compared case sensitively. You can use "*" as a wildcard. The operators < and > can be used to compare strings alphabetically.
By using the following expression, you will get the second person. This expression is very useful; if you want to iterate through the XML document, just replace the number with a variable and it will work.
You can use
to get the last node. This is useful for iterations. There is no function named first().
If you want to select several paths, you can make use of the or ( | ) operator. This will select all name elements and age elements.
/PersonList/Person/Name | /PersonList/Person/Age
These are some of the main XPath expressions that I use and are important.
Sorting is one of the important features that are nearly always required in each project. There are different ways to sort the XML data, but I want to sort the data and make use of XPath at the same time. The best way to do this is to pass a variable to the XSL file that will do the sorting for us. In the following XSL file, I have declared a variable called "sortBy", which holds the value "Name" as the default. This variable will be used to get the sorting parameter from the ASP file. I have also declared another variable called "strXPath", which holds the default value "//Person". This variable is used to get the XPath expression.
Here Is Your XSL File
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- Note that I have specified the default values for the parameters. If no values are passed in, these will be used --> <xsl:param name="sortBy" select="'Name'"/> <xsl:param name="strXPath" select="//Person"/> <xsl:template match="/"> <xsl:apply-templates select="$strXPath"> <xsl:sort select="*[name()=$sortBy]" order="ascending"/> </xsl:apply-templates> </xsl:template> <xsl:template match="Person"> <tr> <td><xsl:value-of select="Name"/></td> <td><xsl:value-of select="Age"/></td> </tr> </xsl:template> </xsl:stylesheet>
In my ASP code, I am using a very simple way to load the XML and XSL files. The only thing to mention is the addParameter function, which is used to pass a parameter from the ASP file to the XSL file. Note that I am passing the parameter "Name" as a sort criteria; instead, I could also pass "Age" or I could use a variable that will be changed dynamically; but I think this part can be done by any of you.
Here Is the ASP Code
<% @ Language=JScript%> <%Server.ScriptTimeout=21478836%> <%Response.Buffer=false%> <html><body> <Center><h2>My Friends</H2> <table border="1" width="100%"> <tr> <td width="50%" bgcolor="red"><b>Name</b></td> <td width="50%" bgcolor="red"><b>Age</b></td> </tr> <%var objXMLDoc = Server.CreateObject( "MICROSOFT.FreeThreadedXMLDOM"); objXMLDoc.async = false; objXMLDoc.load(Server.MapPath("Person.xml")); //a) Build the XPath Query var xmlQuery = "//PersonList/Person[Age>18]"; //b) Create a nodeset for the selected XPath var objNodes = objXMLDoc.selectNodes(xmlQuery); //c) Create an instance of the xslt object var xsl=Server.CreateObject("MICROSOFT.FreeThreadedXMLDOM"); xsl.async = false; xsl.load(Server.MapPath("Person.xsl")); //d) Create an instance of the template object to add the parameter var xslt = Server.CreateObject("Msxml2.XSLTemplate"); xslt.stylesheet = xsl; xslProc = xslt.createProcessor(); xslProc.input = objXMLDoc; xslProc.addParameter("sortBy", "Name"); //Passing in the Sort //Criteria xslProc.addParameter("strXPath", objNodes); //Passing in a Nodeset //as a second //parameter //e)Apply the Transformation and write the results as output xslProc.transform(); var sortedData=xslProc.output; Response.Write(sortedData) %> </Table> </body></html>
Download the source: xpath.zip.
Note: To run the examples, you need to install PWS on Win98 and IIS on Win2K. See the HTML help files of your OS CD to get more info.
About the Author
This article is provided by Sonu Kapoor and is associated with Codefinger (www.codefinger.de), a company specializing in Windows Application Development.
Other Articles by the Author