Last month in, XQJ Part III - Executing queries, we showed through some simple examples how to bind a value to an external variable declared in your query. In this post of the XQJ series, we will get into some more details on this subject.
As we know, XQuery operates on the abstract, logical structure of XML, known as the XQuery Data Model (XDM). As such, by definition in XQuery, the value bound to an external variable is an XDM instance. Having a Java object in your Java application, how is itconverted into such XDM instance? XQJ defines this mapping and glues it all together. A first simple example, [cc lang="java"] ... XQPreparedExpression xqp; XQSequence xqs; xqp = xqc.prepareExpression( "declare variable $id as xs:integer external; " + "doc('orders.xml')//order[id=$id]"); xqp.bindObject(new QName("id"),new Integer(174), null); xqs = xqp.executeQuery(); ...[/cc] The bindObject() method is defined in the XQDynamicContext interface. It provides a number of methods to bind values to external variables. As XQDynamicContext is both the base for XQExpression and XQPreparedExpression, as such both expression implementations support binding values to external variables.Java type | XQuery type | ||
---|---|---|---|
java.lang.Integer | xs:int | ||
java.lang.BigInteger | xs:integer | ||
java.lang.BigDecimal | xs:decimal | ||
java.lang.String | xs:untypedAtomic | ||
org.w3c.dom.Document | untyped document node | ||
org.w3c.dom.Element | untyped element node | ||
... | ... |
XQPreparedExpression xqp; XQSequence xqs;
xqp = xqc.prepareExpression( "declare variable $v1 external; " + "declare variable $v2 external; " + "$v1 instance of xs:integer, "+ "$v1 instance of xs:int, "+ "$v2 instance of xs:integer, "+ "$v2 instance of xs:int"); xqp.bindObject(new QName("v1"),new Integer(174), null); xqp.bindObject(new QName("v2"),new Integer(174), xsinteger); ...[/cc]
This example yields a sequence of 4 xs:boolean instances, [cc lang="java"] true, true, true, false[/cc]A Java Integer is by default mapped to xs:int. xs:int extends by restriction xs:integer, as such the first two 'instance of' expressions evaluate to true. The second external variable is bound with an xs:integer instance as the application explicitly specifies to create such XDM instance. As such the last 'instance of' evaluates to false, as xs:integer is not extending xs:int. Note that various error conditions can occur during the binding process,DocumentBuilder parser = factory.newDocumentBuilder(); Document domDocument = parser.parse("foo.xml"); xqp.bindNode(new QName("e"), domDocument,null); ...[/cc]
The StAX version, [cc lang="java"] ... XMLInputFactory factory = XMLInputFactory.newInstance(); FileInputStream doc = new FileInputStream("foo.xml"); XMLStreamReader reader = factory.createXMLStreamReader(doc); xqp.bindDocument(new QName("e"), reader, null); ...[/cc] And the SAX version, for which we need to implement an XML Filter. [cc lang="java"] ... XMLFilter xmlReader = new XMLFilterImpl() { public void parse(String systemId) throws IOException, SAXException { super.parse("foo.xml"); } }; // the parent XML Reader is a SAX parser, this one will do the actual // work of parsing the XML document xmlReader.setParent(org.xml.sax.helpers.XMLReaderFactory.createXMLReader()); xqp.bindDocument (new QName("e"), xmlReader); ...[/cc] But of course, this is something you only want to use in specific scenarios. The simple use case of binding an xml file, can easily be accomplished in a single line. The XQJ implementation will make sure the XML file is parsed and queried. [cc lang="java"] ... xqp.bindDocument(new QName("e"), new FileInputStream("foo.xml")); ...[/cc] An XQItem or a complete XQSequence can also be bound to an external variable. We’ll discuss this soon in this XQJ series, in a post on pipelining. Talking about pipelining, XQJ also supports the JAXP Source and Result interfaces, these too will be discussed. [1] In this series we have not yet introduced the createAtomicType() method defined on XQDataFactory. This will be handled in the next post. Anyway, for now it’s sufficient to know that it returns an XQItemType object representing the specified atomic type. digg_skin = 'compact'; digg_url = 'http://www.xml-connection.com/2007/09/xqj-part-viii-binding-external.html';View all posts from Marc Van Cappellen on the Progress blog. Connect with us about all things application development and deployment, data integration and digital business.
Let our experts teach you how to use Sitefinity's best-in-class features to deliver compelling digital experiences.
Learn MoreSubscribe to get all the news, info and tutorials you need to build better business apps and sites