dynamic evalution of XQuery
Added by Anonymous about 17 years ago
Legacy ID: #4565973 Legacy Poster: James Fuller (cutlass)
I believe that it is correct to say that there is no current way in Saxon to achieve dynamic evaluation of XQuery code itself .... granted we have saxon:eval(saxon:expression($exp)) where $exp is an XPATH statement. I am trying to achieve some parity with a largish xquery based app that utilizes eXist util:eval which is a superset of saxon:eval in that it evaluates XQuery is well. Any workarounds for this .... or better yet, any plans to reach parity with eXist util:eval function http://demo.exist-db.org/xquery/functions.xq#N10108 (util:eval) I can bend saxon:eval to my will, but would mean that the app I am writing would have significantly different versions for either XQuery processor (which are the target processors for this). I dislike depending on xxx:eval and xxx:evaluate but I find in XQuery apps (if there are such things) of any size it tends to be too useful to ignore. cheers, Jim Fuller
Replies (4)
Please register to reply
RE: dynamic evalution of XQuery - Added by Anonymous about 17 years ago
Legacy ID: #4566155 Legacy Poster: Michael Kay (mhkay)
Seems a reasonable requirement. I'll note it. Michael Kay http://www.saxonica.com/
RE: dynamic evalution of XQuery - Added by Anonymous about 17 years ago
Legacy ID: #4566172 Legacy Poster: James Fuller (cutlass)
many thx for taking this under consideration. I have a good test case if you do decide to implement ;) regards, Jim Fuller
RE: dynamic evalution of XQuery - Added by Anonymous about 17 years ago
Legacy ID: #4567386 Legacy Poster: Michael Kay (mhkay)
Try the following extension functions. Usage: let $q := xx:compile-query("<a/>") return xx:query($q) If xx:query has two arguments, the second is the context item. If it has three, the third argument supplies values of parameters (external variables) in the same way as saxon:transform(). /** * Compile a string containing a source query * @param context the XPath dynamic evaluation context * @param query a string containing the query to be compiled * @return the compiled query / public static XQueryExpression compileQuery(XPathContext context, String query) throws XPathException { if (query == null) { return null; } StaticQueryContext sqc = new StaticQueryContext(context.getConfiguration()); return sqc.compileQuery(query); } /* * Run a previously-compiled query * @param context The dynamic context * @param query The compiled query * @return the sequence representing the result of the query / public static SequenceIterator query(XPathContext context, XQueryExpression query) throws XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); return query.iterator(dqc); } /* * Run a previously-compiled query * @param context The dynamic context * @param query The compiled query * @param source The initial context item for the query (may be null) * @return the sequence representing the result of the query / public static SequenceIterator query(XPathContext context, XQueryExpression query, Item source) throws XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); if (source != null) { dqc.setContextItem(source); } return query.iterator(dqc); } /* * Run a previously-compiled query, supplying parameters to the * transformation. * @param context The dynamic context * @param query The compiled query * @param source The initial context node for the query (may be null) * @param params A sequence of nodes (typically element nodes) supplying values of parameters. * The name of the node should match the name of the parameter, the typed value of the node is * used as the value of the parameter. * @return the results of the query (a sequence of items) */ public static SequenceIterator query(XPathContext context, XQueryExpression query, Item source, SequenceIterator params) throws XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); if (source != null) { dqc.setContextItem(source); } NamePool pool = context.getConfiguration().getNamePool(); while (true) { Item param = params.next(); if (param == null) { break; } if (param instanceof NodeInfo) { switch (((NodeInfo)param).getNodeKind()) { case Type.ELEMENT: case Type.ATTRIBUTE: Value val = ((NodeInfo)param).atomize(); dqc.setParameter(pool.getClarkName(((NodeInfo)param).getNameCode()), val); break; case Type.DOCUMENT: AxisIterator kids = ((NodeInfo)param).iterateAxis(Axis.CHILD, NodeKindTest.ELEMENT); while (true) { NodeInfo kid = (NodeInfo)kids.next(); if (kid == null) { break; } Value val2 = ((NodeInfo)param).atomize(); dqc.setParameter(pool.getClarkName(kid.getNameCode()), val2); } break; default: throw new XPathException( "Parameters passed to saxon:query() must be element, attribute, or document nodes"); } } else { throw new XPathException("Parameters passed to saxon:query() must be nodes"); } } return query.iterator(dqc); }
RE: dynamic evalution of XQuery - Added by Anonymous about 17 years ago
Legacy ID: #4572042 Legacy Poster: James Fuller (cutlass)
damn...I should have tried myself first before asking, was not grokking the xpathcontext because I refuse to RTFM first ;) also, this takes a full xquery, with module imports, etc I have it in my build/test process for the software I am building, thx ... and once again I learn a little bit more about SAXON. btw here is the final file import javax.xml.xpath.XPathException; import net.sf.saxon.expr.XPathContext; import net.sf.saxon.om.Axis; import net.sf.saxon.om.AxisIterator; import net.sf.saxon.om.Item; import net.sf.saxon.om.NamePool; import net.sf.saxon.om.NodeInfo; import net.sf.saxon.om.SequenceIterator; import net.sf.saxon.pattern.NodeKindTest; import net.sf.saxon.query.DynamicQueryContext; import net.sf.saxon.query.StaticQueryContext; import net.sf.saxon.query.XQueryExpression; import net.sf.saxon.type.Type; import net.sf.saxon.value.Value; public class evalXQuery { /** * Compile a string containing a source query * @param context the XPath dynamic evaluation context * @param query a string containing the query to be compiled * @return the compiled query / public static XQueryExpression compileQuery(XPathContext context, String query) throws XPathException, net.sf.saxon.trans.XPathException { if (query == null) { return null; } StaticQueryContext sqc = new StaticQueryContext(context.getConfiguration()); return sqc.compileQuery(query); } /* * Run a previously-compiled query * @param context The dynamic context * @param query The compiled query * @return the sequence representing the result of the query / public static SequenceIterator query(XPathContext context, XQueryExpression query) throws XPathException, net.sf.saxon.trans.XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); return query.iterator(dqc); } /* * Run a previously-compiled query * @param context The dynamic context * @param query The compiled query * @param source The initial context item for the query (may be null) * @return the sequence representing the result of the query / public static SequenceIterator query(XPathContext context, XQueryExpression query, Item source) throws XPathException, net.sf.saxon.trans.XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); if (source != null) { dqc.setContextItem(source); } return query.iterator(dqc); } /* * Run a previously-compiled query, supplying parameters to the * transformation. * @param context The dynamic context * @param query The compiled query * @param source The initial context node for the query (may be null) * @param params A sequence of nodes (typically element nodes) supplying values of parameters. * The name of the node should match the name of the parameter, the typed value of the node is * used as the value of the parameter. * @return the results of the query (a sequence of items) */ public static SequenceIterator query(XPathContext context, XQueryExpression query, Item source, SequenceIterator params) throws XPathException, net.sf.saxon.trans.XPathException { if (query == null) { return null; } DynamicQueryContext dqc = new DynamicQueryContext(context.getConfiguration()); if (source != null) { dqc.setContextItem(source); } NamePool pool = context.getConfiguration().getNamePool(); while (true) { Item param = params.next(); if (param == null) { break; } if (param instanceof NodeInfo) { switch (((NodeInfo) param).getNodeKind()) { case Type.ELEMENT: case Type.ATTRIBUTE: Value val = ((NodeInfo) param).atomize(); dqc.setParameter(pool.getClarkName(((NodeInfo) param).getNameCode()), val); break; case Type.DOCUMENT: AxisIterator kids = ((NodeInfo) param).iterateAxis(Axis.CHILD, NodeKindTest.ELEMENT); while (true) { NodeInfo kid = (NodeInfo) kids.next(); if (kid == null) { break; } Value val2 = ((NodeInfo) param).atomize(); dqc.setParameter(pool.getClarkName(kid.getNameCode()), val2); } break; default: throw new XPathException("Parameters passed to saxon:query() must be element, attribute, or document nodes"); } } else { throw new XPathException("Parameters passed to saxon:query() must be nodes"); } } return query.iterator(dqc); } }
Please register to reply