{"id":311,"date":"2012-06-07T01:39:10","date_gmt":"2012-06-07T01:39:10","guid":{"rendered":"http:\/\/corneliadavis.com\/blog\/?p=311"},"modified":"2012-06-07T01:39:10","modified_gmt":"2012-06-07T01:39:10","slug":"passing-parameters-to-an-xquery-or-xslt-through-an-xproc-pipeline","status":"publish","type":"post","link":"https:\/\/corneliadavis.com\/blog\/2012\/06\/07\/passing-parameters-to-an-xquery-or-xslt-through-an-xproc-pipeline\/","title":{"rendered":"Passing parameters to an XQuery or XSLT through an XProc Pipeline"},"content":{"rendered":"<p><em>(syndicated from<a href=\"https:\/\/community.emc.com\/docs\/DOC-17045\"> original posting on the EMC Community Network<\/a>)<\/em><\/p>\n<div>\n<p>I&#8217;ve recently been helping someone get started with the <a href=\"https:\/\/community.emc.com\/docs\/DOC-10494\">XML REST Framework<\/a>,  and they asked about getting query string parameters into the XQueries  or XSLTs that were a part of their resource implementation.\u00a0 For those of  you who are not familiar, what the XML REST Framework does is leverages  Spring MVC for all of the HTTP protocol stuff, a developer builds a  very thin Java shim to an XProc pipeline that implements the RESTful  service.\u00a0 The post I link to above and <a href=\"https:\/\/community.emc.com\/docs\/DOC-6434\">two<\/a> <a href=\"https:\/\/community.emc.com\/docs\/DOC-6485\">earlier<\/a> versions explain this all in more detail.\u00a0 What I am focusing on in  this post is how I can get values from the query string into the right  places within my pipeline; there are two parts to this.\u00a0 1) you need to  get your hands on the query string argument and 2) you need to pass that  into the XProc pipeline in such a way that it gets to the XQuery or  XSLT.\u00a0 It turns out that #2 was already demonstrated in the  Patients.java class file in combination with the resourceGET.xpl.\u00a0 Let\u2019s  drill in on that a little bit.<\/p>\n<p>If  you take a look at the top of the xpl you see the following code \u2013  really declarations of the inputs and outputs for the pipeline.<\/p>\n<pre><code>&lt;p:declare-step name=\"main\" xmlns:p=\"<a href=\"http:\/\/www.w3.org\/ns\/xproc\" target=\"_blank\">http:\/\/www.w3.org\/ns\/xproc<\/a>\"\n\u00a0\u00a0\u00a0\u00a0 xmlns:c=\"<a href=\"http:\/\/www.w3.org\/ns\/xproc-step\" target=\"_blank\">http:\/\/www.w3.org\/ns\/xproc-step<\/a>\" version=\"1.0\"&gt;\n\u00a0\u00a0 &lt;p:input port='xqueryscript' \/&gt;\n\u00a0\u00a0 &lt;p:input port=\"stylesheet\"\/&gt;\n\u00a0\u00a0 &lt;p:input port=\"stylesheetParameters\" kind=\"parameter\"\/&gt;\n\u00a0\u00a0 &lt;p:input port=\"xqueryParameters\" kind=\"parameter\"\/&gt;\n\u00a0\u00a0 &lt;p:output port='result' sequence='true' primary='true' \/&gt;\n\u00a0\u00a0 &lt;p:output port='error' sequence=\"true\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step='checkXquery' port='error' \/&gt;\n\u00a0\u00a0 &lt;\/p:output&gt;\n\u2026\n<\/code><\/pre>\n<p>You\u2019ll note two different input ports for parameters, one called stylesheetParameters and the other xqueryParameters;  these were names of my choosing (just like parameters in any other  language would be.) A parameter input port is named and the value is a  list of keyword value pairs; that\u2019s right, a parameter input port  actually carries a set of key\/value pairs (Norm Walsh, XML guru and one  of the lead authors on the XProc spec says \u201c[XProc] parameters suck.\u201d \u2013  they are kinda weird and we are thinking about changing things in the  next version of XProc).\u00a0 In this example, I built the pipeline to keep  the XQuery parameters separate from the XSLT ones; if I wanted to have a  key\/value pair passed down into both my XQuery and my XSLT, at the java  level I could just add that pair to both parameters.\u00a0 So speaking of  that, our framework allows you to add parameters to the pipeline input  with a call to the addParameter method:<\/p>\n<pre><code>pi.addParameter(<span style=\"color: red;\">\"stylesheetParameters\"<\/span>, <span style=\"color: navy;\"><strong>new<\/strong><\/span> QName(<span style=\"color: red;\">\"baseURL\"<\/span>), request.getRequestURL().toString());\n<\/code><\/pre>\n<p>Going back to the xpl then, let\u2019s look at how the input  parameters to the pipeline make their way down into the XQuery or XSLT.  In each case, we just pass the parameter from the main pipeline down  into the appropriate step.\u00a0 XProc is nice that way and while the current  parameter design might feel a bit odd, it does enable this easy, easy  approach.<\/p>\n<p>For XQuery:<\/p>\n<pre><code>&lt;p:xquery name=\"xquery\"&gt;\n\u00a0\u00a0 &lt;p:input port='source'&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:document href=\"xhive:\/\" \/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n\u00a0\u00a0 &lt;p:input port=\"query\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step=\"main\" port=\"xqueryscript\" \/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n\u00a0\u00a0 &lt;p:input port=\"parameters\"&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step='main' port='xqueryParameters'\/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n&lt;\/p:xquery&gt;\n<\/code><\/pre>\n<p>And for XSLT:<\/p>\n<pre><code>&lt;p:xslt&gt;\n\u00a0\u00a0 &lt;p:input port='source'&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step='xquery' port='result'\/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n\u00a0\u00a0 &lt;p:input port='stylesheet'&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step='main' port='stylesheet'\/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n\u00a0\u00a0 &lt;p:input port='parameters'&gt;\n\u00a0\u00a0\u00a0\u00a0\u00a0 &lt;p:pipe step='main' port='stylesheetParameters'\/&gt;\n\u00a0\u00a0 &lt;\/p:input&gt;\n&lt;\/p:xslt&gt;\n<\/code><\/pre>\n<p>So then the only thing that remains is how to get your  hands on the query string argument (#1 of the two things we needed to do) and because our framework uses Sprint  MVC for our REST protocol layer, this is in the Java code. The  following method could be added to the Patients.java class of the <a href=\"https:\/\/community.emc.com\/docs\/DOC-10494\">sample application<\/a>, to show this:<\/p>\n<pre><code>@RequestMapping(method = RequestMethod.GET, value=<span style=\"color: red;\">\"\/alt\"<\/span>)\n@ResponseStatus(HttpStatus.OK)\n<span style=\"color: navy;\"><strong>public<\/strong><\/span> String getPatientAlt(HttpServletRequest request, HttpServletResponse response, Model model, @RequestParam(<span style=\"color: red;\">\"pid\"<\/span>) String pid)\n <span style=\"color: navy;\"><strong>throws<\/strong><\/span> XProcException, TransformerException, IOException <span style=\"color: navy;\">{<\/span>\n\n\u00a0 <span style=\"color: navy;\"><strong>try<\/strong><\/span> <span style=\"color: navy;\">{<\/span>\n\n\u00a0\u00a0\u00a0 PipelineInputCache pi = <span style=\"color: navy;\"><strong>new<\/strong><\/span> PipelineInputCache();\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <span style=\"color: darkgreen;\">\/\/ pass the patient ID into the pipeline for use in the xQuery (to look up the right patient)<\/span>\n\u00a0\u00a0\u00a0 pi.addParameter(<span style=\"color: red;\">\"xqueryParameters\"<\/span>, <span style=\"color: navy;\"><strong>new<\/strong><\/span> QName(<span style=\"color: red;\">\"pid\"<\/span>), pid);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <span style=\"color: darkgreen;\">\/\/ supply current resource URL as the base URL to craft hyperlinks<\/span>\n\u00a0\u00a0\u00a0 pi.addParameter(<span style=\"color: red;\">\"stylesheetParameters\"<\/span>, <span style=\"color: navy;\"><strong>new<\/strong><\/span> QName(<span style=\"color: red;\">\"baseURL\"<\/span>), request.getRequestURL().toString());\n\n\u00a0\u00a0\u00a0 PipelineOutput output = m_getPatient.executeOn(pi);\n\n\u00a0\u00a0\u00a0 model.addAttribute(<span style=\"color: red;\">\"pipelineOutput\"<\/span>, output);\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 <span style=\"color: navy;\"><strong>return<\/strong><\/span> <span style=\"color: red;\">\"pipelineOutput\"<\/span>;\n\u00a0 <span style=\"color: navy;\">}<\/span> <span style=\"color: navy;\"><strong>finally<\/strong><\/span> <span style=\"color: navy;\">{<\/span>\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ;\n\u00a0 <span style=\"color: navy;\">}<\/span>\n<span style=\"color: navy;\">}<\/span>\n<\/code><\/pre>\n<p>The ONLY difference between this and the original  getPatient method is where I get the value for the patient ID that I  will pass down into the XQuery.\u00a0 The way that Sprint MVC does this is  with the @RequestParam annotation.\u00a0 You can see that for testing I  changed the @RequestMapping path to be \/alt so the URL that will invoke this code is something of the form:<\/p>\n<pre><a href=\"http:\/\/example.com\/XProcPatientServiceMVC\/patients\/alt?pid=12345\">http:\/\/example.com\/XProcPatientServiceMVC\/patients\/alt?pid=12345<\/a><\/pre>\n<p>Note  that I didn\u2019t even have to create a new XProcXMLProcessingContext  because I just reused all of the implementation from the original get  patient \u2013 I\u2019m just getting the value for the passed in parameter from  somewhere else.<\/p>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>I&#8217;ve recently been helping someone get started with the XML REST Framework, and they asked about getting query string parameters into the XQueries or XSLTs that were a part of their resource implementation.  For those of you who are not familiar, what the XML REST Framework does is leverages Spring MVC for all of the HTTP protocol stuff, a developer builds a very thin Java shim to an XProc pipeline that implements the RESTful service.  The post I link to above and two earlier versions explain this all in more detail.  What I am focusing on in this post is how I can get values from the query string into the right places within my pipeline; there are two parts to this.  1) you need to get your hands on the query string argument and 2) you need to pass that into the XProc pipeline in such a way that it gets to the XQuery or XSLT.  It turns out that #2 was already demonstrated in the Patients.java class file in combination with the resourceGET.xpl.  Let\u2019s drill in on that a little bit.<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[13,41],"tags":[80,95,96,97,98],"class_list":["post-311","post","type-post","status-publish","format-standard","hentry","category-howto","category-xml","tag-rest","tag-xmlrest","tag-xproc","tag-xquery","tag-xslt"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/311","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/comments?post=311"}],"version-history":[{"count":0,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/posts\/311\/revisions"}],"wp:attachment":[{"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/media?parent=311"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/categories?post=311"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/corneliadavis.com\/blog\/wp-json\/wp\/v2\/tags?post=311"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}