Recommended: Sing it, brah! 5 fabulous songs for developers
JW's Top 5
Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs
Page 4 of 5
public Node findAddress(String name, Document source) throws Exception {
XPathHelper xpathHelper = new XPathHelper();
NodeList nl = xpathHelper.processXPath(
"//address[child::addressee[text() = '"+name+"']]",
source.getDocumentElement());
return nl.item(0);
}
The helper class can now be used whenever a node or a set of nodes needs to be located in a given XML document. The actual XPath statement could even be loaded from an external source, so that changes could be made on the fly if the source document structure changes. In this case, no recompile is necessary.
In some cases, it makes sense to outsource the entire handling of an XML document to an external XSL stylesheet, a process in some respects similar to the use of XPath as described in the previous section. With XSL stylesheets, you can create an output document by selecting nodes from the input document and merging their content with stylesheet content, based on pattern rules.
If an application changes the structure and content of an XML document and producing a new document, it may be better and easier to use a stylesheet to handle the work rather than writing a Java program that does the same job. The stylesheet is most likely stored in an external file, allowing you to change it on the fly, without the need to recompile.
For example, we could accomplish the processing for the addressbook sample by creating a stylesheet that merges the cached version of the addressbook with the updated one, thus creating a new document with the updates in it.
Here is a sample of such a stylesheet:
<?xml version='1.0'?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"/>
<xsl:variable name="doc-file">http://mymachine.com/changed.xml</xsl:variable>
<!-- copy everything that has no other pattern defined -->
<xsl:template match="* | @*">
<xsl:copy><xsl:copy-of select="@*"/><xsl:apply-templates/></xsl:copy>
</xsl:template>
<!-- check for every <address> element if an updated one exists -->
<xsl:template match="//address">
<xsl:param name="addresseeName">
<xsl:value-of select="addressee"/>
</xsl:param>
<xsl:choose>
<xsl:when test="document($doc-file)//addressee[text()=$addresseeName]">
<xsl:copy-of select="document($doc-file)//address[child::addressee[text()=$addresseeName]]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Note that the above stylesheet takes the updated data out of a file called changed.xml. A real application would obviously not want to store the changed data in a file before processing it. One solution is to
add a special attribute to the <address> element, indicating whether or not it has been updated. Then the application could simply append the updated data to the
source document and define a different stylesheet that detects updated records and replaces the outdated ones.
All the application has to do now is create an XSLTProcessor object and let it do the work: