DIY编程器网

 找回密码
 注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 960|回复: 0
打印 上一主题 下一主题

[待整理] XQJ解析 用于XQuery查询的Java API

[复制链接]
跳转到指定楼层
楼主
发表于 2014-10-13 15:20:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
查询是用于查询XML的声明性语言,类似于用于查询关系数据的SQL。大部分Java程序员熟悉JDBC,它提供了标准的Java API来和各种关系数据库的SQL引擎进行交互。XQJ具有相同的目的:它向Java程序员提供了标准的Java API用于和各种XML数据源的XQuery引擎进行交互。
  XQJ也被称为JSR 255,因为它是由Java Community Process设计的。这个JSR 255规范定义了接口和Class集合,用于Java应用能够向一个XQuery引擎对一个或者多个XML数据源提交XQuery查询和使用查询结果。这篇文章通过给出基本的用况(use-case)来提供对XQJ的介绍,并且讨论了作为XQuery基础的XQJ中的几个关键的接口。此外,这篇文章强调了XQL和JDBC之间的不同之处。
  对那些熟悉JDBC的程序员而言比较幸运的是,XQJ遵守了几个熟悉的模式。执行一个查询的典型编码顺序——获得连接(connection),准备XQuery表达式,在已经准备好的XQuery表达式中的值和变量绑定起来,执行表达式,使用XQuery结果并且清理资源——是和JDBC的次序基本一致。然而,XQuery中的几个关键概念要求创建XQJ中的专用接口,比如static context、dynamic context、XQuery data model和XQuery Sequence Type。进一步,在XQuery数据模型中一个主要元素是XML node。XQJ需要和现有的XML节点操作API如DOM、SAX和StAX等相结合。XQuery允许节点通过XMLSchema定义类型。XQJ通过XQuery Sequence Type接口定义和XMLSchema的关系。
  一个简单的例子
  下面是简单的、使用XQJ来执行查询的代码示例,演示了典型的使用情况。注意为了简单起见,错误处理已经被忽略了。
   // obtain an XQDataSource instance
               XQDataSource xqds = (XQDataSource)
                  Class.forName("com.jsr225.xqj").newInstance();
               
               // obtain a connection
               XQConnection con = xqds.getConnection("usr", "passwd");
               
               // prepare an XQuery Expression
               String xqry = "for $i in fn:collection('dept') " +
                  "where $i/deptname = %dname return count($i/employees)";
               XQPreparedExpression expr = con,preparedExpression(xqry);
               
               // bind variable with value
               expr.bindString(new Qname("dname"), "engineering");
               
               // execute the XQuery Expression
               XQResultSequence rs = expr.executeQuery();
               
               // Consume results
               while (rs.next())
               {
                 System.out.printLn(rs.getInt());
               }
               
               // clean up resources
               rs.close();
               con.close();

  在上面的例子中,XQDataSource是你用来获得XQuery连接的接口。你可以通过典型的数据源实例化机制,比如JNDI查询或者显式的类装载方法来创建XQDataSource 接口初始实现类。这类似于JDBC的DataSource和Connection接口的设计。
在获得了XQConnection之后,你可以通过XQExpression或者XQPreparedExpression接口来执行XQuery。假如你只执行XQuery表达式一次,那么你应该使用XQExpression,并且如果你要准备XQuery表达式一次而使用不同的绑定值来多次执行这个表达式,像在前面的例子中那样,那么你应该使用XQPreparedExpression。这两个接口分别类似于JDBC中的Statement和PreparedStatement概念。
  XQuery结果是XQuery数据模型的一个实例。在例子中显示的XQResultSequence提供了以光标为中心的接口,允许用户在结果的sequence中迭代每一个元素。用户可以从每个元素获得值,或者是原子数值或者XML节点。这类似于JDBC结果集中的迭代。
  在使用完XQuery结果之后,程序员需要对XQResultSequence和XQConnection接口调用close()方法来清理这些资源。合理的用于释放资源的错误处理代码对避免资源泄露非常关键。在sequence结果关闭的时候,这个框架隐含的关闭从sequence结果中创建的元素。类似的,在连接被关闭的时候,这个sequence结果也被隐含的关闭了。
  XQuery上下文(Context)的支持
  XQuery有双重的“上下文”概念:静态的上下文和动态的上下文。XQJ提供了XQStaticContext和XQDynamicContext接口来为它们建模。XQStaticContext提供了方法检索定义在XQuery静态上下文中的信息,比如base URI、the boundary-space policy等等,允许应用检索关于全局静态上下文中的信息。比如,XQConnection接口扩展了XQStaticContext接口。
  相比之下,XQDynamicContext接口让应用检索关于动态上下文的信息,并且改变这些信息。尤其,它提供方法绑定XQuery变量到各种数值,这些变量是动态上下文的一部分。XQPreparedExpression和XQExpression接口都扩展XQDynamicContext。上面的例子可以对XQPreparedExpression调用bindString()方法,因为bindString()是基类的XQDynamicContext接口中定义的方法。
  和JDBC不同的是由于绑定到XQuery变量的值不一定是简单的标量值,XQDynamicContext中的bindXXX()方法可以有一种延迟绑定模式(deferred binding mode)。在延迟绑定模式中,这个绑定的数值可能直到XQuery处理器真正的访问了该变量才会被使用,这让XQJ潜在的使用基于流水线的惰性数值赋值模型。
  XQuery数据模型的支持
  再次,XQuery的结果是XQuery数据模型的一个实例,它由XQuery元素的序列组成。每个元素可以是原子数值或者XML节点(文档, 元素, 属性, 注释, 处理指令, 或者文本)。XQSequence接口建模XQuery数据模型。它包含零个或者多个XQItem接口对象。XQItem接口代表了XQuery 数据模型中的元素。程序员通过调用XQSequence.getItem()或XQConnection.createItem()方法获得XQItem 。
  虽然XQItem和XQSequence代表了独立于XQuery结果的XQuery的元素和序列,XQResultItem和XQResultSequence(分别扩展了XQItem和XQSequence)代表了从XQuery执行结果中得到的XQuery元素和序列。
  如果XQItem是原子数值,你可以使用某种getXXX()方法将它转换到对应的Java数据类型,这些方法包括getInt()、getString()等等。假如XQItem是XML节点,你可以通过已有的XML节点操作接口访问它,这些接口包括DOM、SAX或者StAX。XQItem和XQSequence都扩展了XQItemAccessor接口,该接口定义了各种元素访问方法。比如,getNode()方法返回了DOM节点。writeItemToSAX()方法通过将序列顺序化为SAX事件来产生SAX事件。getItemAsStream()方法将序列顺序化为XMLStreamReader事件流。进一步,XQJ定义了一套进行Java数据类型和XQuery数据类型之间的标准映射,来辅助将标准的Java类型绑定到XQuery变量。

       XQuery类型系统的支持
  XQuery有类型——并且还有支持它们的接口。XQSequenceType和XQItemType接口允许用户使用XQuery类型系统。XQSequenceType接口代表了XQuery中定义的序列类型(sequence ),而XQItemType接口代表了XQuery中定义的元素类型(item type) 。XQItemType扩展了XQSequenceType 但是将出现次数限制为1。XQItem接口包含了获得关于XQuery元素类型信息的方法,比如元素类型、基础类型、节点名(如果有的话)、节点类型名(如果有的话)以及和类型有联系的任何XML Schema URI。
  XQJ给予了实现很大的自由处理XML模式类型。因为XQJ被设计为能够和各种XQuery引擎协同工作,你不能为XQJ的实现和底层的XQuery引擎之间假设任何特定的关系。因此你不能假设某个XQJ的时间和XQuery引擎会共享相同的XML模式仓储。为了解决这个问题,XQJ API使用叫做isUserDefinedXMLSchemaTypeSupported()的XQMetaData方法来判断是否XQJ的实现可以回答关于对XML模式依赖的问题。对于紧耦合的系统,XQuery引擎和XQJ实现共享了相同的XML模式仓储,isUserDefinedXMLSchemaTypeSupported 就会返回ture,对于松耦合的系统,这个值被设为false。
  使用XQMetaData
  XQMetaData接口为用户提供了关于底层XQJ和XQuery实现的额外的信息。它包含方法查询某些特定的XQuery的功能,比如StaticTypingFeature和SchemaImportFeature,是否被支持。它还提供了关于数据源的通用信息。XQMetaData接口为XQJ用户起到了可移植层的作用。这类似于JDBC中的DatabaseMetaData接口。
  未来的发展方向
  随着SQL/XML成为标准,程序员将能够在SQL中嵌入和执行XQuery——这样JDBC最终会支持XQuery。但是,我们相信XQJ仍然是必要的,由于不是所有的需要XQJ的XQuery处理器都支持SQL和SQL/XML。进一步,XQJ已经定义了一些重要的接口(上面已提到)来建模XQuery中的关键概念,以及经典的XML Java接口,比如DOM、SAX和StaX。当JDBC最终支持SQL/XML 2006,它让SQL调用XQuery,这些XQJ接口会被使用。潜在的集成点是让JDBC XMLType支持一个使用XQJ定义的接口来创建XQuery数据模型。
  这篇文章对XQJ(XQuery Java API)进行了简要的介绍,并且讨论了一些为XQuery中的关键概念进行建模的接口。如同JDBC在关系数据库中的成功,我们相信XQJ会成为对XML数据源的XQuery引擎进行交互中最广泛使用的Java API.
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
收藏收藏 分享分享 支持支持 反对反对
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|文字版|手机版|DIY编程器网 ( 桂ICP备14005565号-1 )

GMT+8, 2025-1-11 10:10 , 耗时 0.085409 秒, 19 个查询请求 , Gzip 开启.

各位嘉宾言论仅代表个人观点,非属DIY编程器网立场。

桂公网安备 45031202000115号

DIY编程器群(超员):41210778 DIY编程器

DIY编程器群1(满员):3044634 DIY编程器1

diy编程器群2:551025008 diy编程器群2

QQ:28000622;Email:libyoufer@sina.com

本站由桂林市临桂区技兴电子商务经营部独家赞助。旨在技术交流,请自觉遵守国家法律法规,一旦发现将做封号删号处理。

快速回复 返回顶部 返回列表