[MarkLogic Dev General] MarkLogic XQuery Tag Library and JSTLXMLTag Library

Alan Darnell alan.darnell at utoronto.ca
Wed Apr 4 14:14:36 PDT 2007


Thanks for this.  The alternative model you describe works great if  
I'm returning a single value from Mark Logic.  But what if I want to  
get back multiple values from Mark Logic for each document (e.g.  
author, title, abstract, journal title) so I can display these to the  
user.  Can I store these in a structure in the "results" variable so  
I can pull each of these  out when I iterate over results?  Or is  
this something better done in a servlet with the results stored in a  
collection of beans and accessed from the JSP page?  What are good  
models for using Mark Logic in a J2EE context.

Alan


On 4-Apr-07, at 4:41 PM, Ron Hitchens wrote:

>
>    I tinkered with this for a while and got it
> working.  There are a couple of issues to address.
>
>    The reason for the exception you're seeing is
> that the JSTL jars in the Mark Logic JSP bundle
> are old and are referring to an external XPath
> library that isn't included.  Updating the JSTL
> jars (jstl.jar and standard.jar) to the latest
> release should make the XML tags work as expected.
> I will update the JSP bundle as soon as I can.
>
> [http://jakarta.apache.org/site/downloads/downloads_taglibs- 
> standard.cgi]
>
>
>    There are a couple of other things I want to
> discuss about your example.  The first is an
> important security issue.  You're building up
> your query by inserting a string obtained from
> a user-supplied parameter.  This leaves you open
> to code injection attacks and/or spurious failures
> caused by garbled input.
>
>    Rather than this:
>
>     <xq:execute var="results">
>         <xq:query>
>             for $i in cts:search(doc()//article-title,"$ 
> {param.query}") [1 to 15]
>             return $i/root()
>         </xq:query>
>     </xq:execute>
>
>    Pass the user-supplied value as an external variable:
>
>     <xq:execute var="results">
>         <xq:query>
>             define variable $term as xs:string external
>
>             for $i in cts:search(doc()//article-title,$term) [1 to 15]
>             return $i/root()
>         </xq:query>
>         <xq:variable localname="term" type="xs:string" value="$ 
> {param.query}"/>
>     </xq:execute>
>
>
>    But more significantly, unless you really, really
> need to use the JSTL XML tags for some reason I recommend
> not using them at all and doing all the XML and XPath
> work in your Mark Logic queries.  For example, here is
> a modification that gives the same result using only
> the core JSTL tags:
>
>     <xq:execute var="results">
>         <xq:query>
>             define variable $term as xs:string external
>
>             for $i in cts:search(doc()//article-title,$term) [1 to 15]
>                 return fn:string($i/root()//journal-id)
>         </xq:query>
>         <xq:variable localname="term" type="xs:string" value="$ 
> {param.query}"/>
>     </xq:execute>
>
>     <ol>
>
>     <c:forEach var="item" items="${results.items}">
>         <li>
>             <c:out value="${item.string}" escapeXml="true"/>
>         </li>
>     </c:forEach>
>
>     </ol>
>
>    This query returns only the journal IDs rather than the full
> documents, which is far more efficient for the JSP container.
>
>    Another way to do this, without using any JSTL tags
> at all, is to use the looping xq:result tag (note that the
> xq:execute tag no longer has a "var" attribute):
>
>     <xq:execute>
>         <xq:query>
>             define variable $term as xs:string external
>
>             for $i in cts:search(doc()//article-title,$term) [1 to 15]
>             return fn:string($i/root()//journal-id)
>         </xq:query>
>         <xq:variable localname="term" type="xs:string" value="$ 
> {param.query}"/>
>
>         <h2>Search results</h2>
>         <ol>
>         <xq:result>
>             <li><xq:streamItem/></li>
>         </xq:result>
>         </ol>
>     </xq:execute>



More information about the General mailing list