Brian makes the curious observation under the heading Using XQuery prevents "cheating" that "You cannot write business logic in XQuery because XQuery focuses exclusively on querying and transformation". This rather ignores the fact that a significant number of applications are built soley on XQuery as the server-side language. The consequence is that a simple Web application retains a complex and unnnecessary Java middle tier acting as Controller in an MVC architecture.
Brian's web application provides a browsing interface to a collection of products using AJAX to update the page and XQuery to select producats and transfrom to an HTML table.
Implemented in XQuery on the open source eXist XML database as an example, we need only use the HTTP interface functions provided to couple the HTTP requests directly to the XQuery script. For eXist the additions would be:
declare variable $docName as xs:string := "lures.xml";
declare variable $configuration as xs:string := request:get-parameter("configuration",());
declare variable $usage as xs:string:= request:get-parameter("usage",());
It might be objected that this script binds the resources and interfaces too closely to the script. Indeed the only benefit of the Java controller layer is this de-coupling. We can achieve the same effect in XQuery with a local configuration file to aid portability and testing:
<ConfigurationFile>
<lureFileName>/db/Wiki/BC/lures2.xml</lureFileName>
</ConfigurationFile>
and adding these lines to the XQuery script:
declare variable $config := /ConfigurationFile;
declare variable $docName := $config/lureFileName;
I've implemented Brian's code with eXist on the XQuery Wikibook server and the relevant scripts are here:
http://www.cems.uwe.ac.uk/~cjwallac/apps/BC/index.html
I changing only the script address in the HTML code and correcting an error in the AJAX function where request.readyState was miss-typed. (took me a while to track that down!). Middle layer all gone. Storage of the whole application in eXist would be a normal deployment but was not possible without editing because the HTML page is not valid XHTML .
One impediment to the use of XQuery as an application development language is that functions to extend the XPath function with functionality such as HTTP interfacing are implementation-dependent, limiting portability. A new inititive EXQuery seeks to remedy this problem by developing a cross-platform library.
One other feature of Brian's implementation is the structure of the XML file. The start of the file looks like
<lures>
<casting>
<minnows brand="Yohuri" style="deep" size="3">
<minnow color="midnight blue">
But since the data is intended to be searched for usage(e.g. casting) and configuration (e.g. minnow) this leads to XQuery code like
if ($configuration = 'minnow' and $usage = 'casting') then
for $minnows in doc($docName)//casting/minnows
return
else
else if ($configuration = 'minnow' and $usage = 'trolling') then
..
and because the child structures are actually all the same, this leads to unmaintableable and repetative code.
A fix is possible in XQuery using local-name to filter using the node names themselves. A better approach would be to flatten the whole file, changing the representation of the configuration and usage concepts from elements to attributes:
<lures>
<lure brand="Yohuri" style="deep" size="3" color="midnight blue" usage="casting" configuration="minnow">
..
and the query becomes
for $lure in doc($docName)//lure[@configuration = $configuration][@usage=$usage]
return ..
In summary, this implementation might be a "cheat" but cheating by reducing complexity and lines of code seems a good thing to do.
1 comment:
+1 to that!
Post a Comment