This evening, I took my first dive into XPath, and I have to say, navigating XML documents using JSTL tags and XPath is incredibly easy.
The reason I had to parse an XML document is because one of the features I added for Argus 0.9 was a system that would allow an administrator to upgrade the database easily when deploying a new version of the software. After a successful upgrade, I displayed a list of new features, improvements and bug fixes for that version. What I had envisioned though, is dynamically generating this list, from an XML file.
So how do you use JSTL and XPath to parse your XML document? Well, first off, you have to import and parse your XML file:
<c:import url="changelog.xml" var="url"/>
<x:parse xml="${url}" var="changelog"/>
After you do this, you now have a parsed XML document that you can start selecting elements from. Let's take a section of my changelog XML to work with.If you want to iterate over all of the the<log><changes version="0.9.2"><fix>Fixed a changelog email bug while trying to load users with permission.</fix></changes><changes version="0.9.1"><fix>Hid the 'Assigned to me' scope for regular users.</fix></changes><changes version="0.9"><feature>Upgrade script that can upgrade the database from any older version to the current version.</feature><feature>Personalized ticket scopes added to the filter bar.</feature><improvement>'Revisions' renamed as 'Versions'.</improvement><improvement>Revision live and beta abandoned for simple 'released' flag.</improvement><improvement>Ability to manually set the sort order for Versions.</improvement><improvement>Ability to remove the version selected for a ticket.</improvement><fix>Ticket description no longer gets truncated during an update.</fix></changes></log>
changes elements, you can use the x:forEach tag:
<x:forEach select="$changelog//changes">
The key to using XPath syntax, though, is to know where you are in the XML document's DOM. For example, during each iteration, the top level object is a changes element. So your XPath syntax should be relative to that object. Let's say that the first thing we want to do is display the version attribute of the current changes element. We would do:Now, what if wanted to iterate over all<x:out select="@version"/>
feature elements that are children of this changes element? Well, we could do something like this:As you can see, the XPath syntax is pretty straightforward and if you are familiar with navigating a UNIX based operating system, you will see some similarities. A '.' is used to denote the current element and a slash and then an element name means all elements with that name that are children of this node. While inside this x:forEach tag, remember that the current element will be a<x:forEach select="./feature">
feature element. If you want to display the contents of each feature element, you would again use x:out like this:So, why don't you give it a try. But, don't forget that you'll need to import<x:out select="."/>
<%@ taglib prefix="x" uri="http://java.sun.com/jsp/jstl/xml" %> and have the JSTL jar in your project.