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>

_______________________________________________
General mailing list
[email protected]
http://xqzone.com/mailman/listinfo/general

Reply via email to