[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