`
ammayjxf
  • 浏览: 68242 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

建立 XQuery

阅读更多
在Java环境中使用XQuery2008年10月19日 星期日 17:07为了在 Java 环境中使用 XQuery,我们要选择 XQJ(常见的 Java XQuery API 缩写)。

XQuery 规范是供应商中立的

XQuery for Java API 是在 Sun 的支持下作为 Java Community Process, JSR 225的一部分开发的。规范本身涉及到多个不同的供应商(包括 Sun、Nokia、BEA、Oracle、Intel 等)和一些知名人士(比如 Jason Hunter,servlet、JDOM 和 XML 方面的名人)。因此,能够避免维系于特定的数据库供应商或者 XML 产品厂家。

但 XQJ 的实现不是中立的

不幸的是,还没有 XQJ 的 Sun 的标准实现。专家组的多数供应商都致力于在其产品中提供 XQJ 实现,这就意味着必须解决某些和特定供应商有关的问题。当然,对于长期使用 XML 的人来说,这和二十世纪初的 XML 解析器与 XSL 处理程序之争没有什么区别。随着时间的推移 XQJ 将标准化,Sun 几乎肯定会发布自己的 XQJ 版本或者 XQJ 实现的包装器 API,就像 XML 解析器与 XSL 处理程序的 JAXP 一样。

获得 XQJ 实现

学习 XQJ 最简单的办法是从 DataDirect 下载免费的试用版。下载地址。

展开 JARred JAR

安装过程有点麻烦,首先需要解压下载的 datadirectxquery.jar。可以使用 jar 命令。但首先要建立安装目录,然后将 JAR 文件解压到该目录。

运行安装程序

现在打开新建的目录并双击 XQueryInstaller.jar 文件。如果系统中安装了 Java,将打开 GUI 安装程序。

或者使用命令java -jar XQueryInstaller.jar运行安装程序。

安装程序开始后一路next

提示您选择试用版还是注册版,选择Evaluation Installation。

继续next到最后点Install。之后点Finish。

将 XQJ JAR 添加到类路径

把xquery安装路径里lib文件夹里的ddxq.jar添加到你Eclipse的项目里。具体操作:右击项目点Property,左侧点击Java Build Path,选择Libraries,点Add External Jars,选择你安装xquery里lib文件夹的ddxq.jar,就添加成功了。

建立数据库连接

DataDirect 下载也提供了数据库连接功能,从而能够对关系数据库运行 XQuery。然后 DataDirect 定制下载以便能够设置数据库。这超出了本文的讨论范围,但是如果除了对磁盘上的 XML 文档使用 XQuery 外,也对使用 DataDirect 库连接到数据库感兴趣。安装的 lib 目录中还有其他很多 JAR 文件,但是简单的文件查询用不到这些文件。如果以后使用 DataDirect 数据库连接,也可研究一下这些 JAR。

在 Java 中运行 XQuery

掌握了 XPath 和 XQuery 并且类路径中有了 XQJ 实现之后,就可以编写 Java 代码运行查询了。每个程序都包含两个基本的步骤:

建立/访问 XQuery 数据源。
执行 XQuery。
这两个步骤都很简单,而且只要不改变 XQuery 实现,在所有程序中第一步都是一样的。实际上可以将处理数据源配置和连接的代码打包成一个工具类(留给读者作为练习)。

处理 XQuery 数据源

数据源和数据库

对于 DataDirect 这类希望在静态 XML 查询之外提供数据库连接功能的供应商来说,数据源是一个关键。一旦建立了连接对象,就可以对其运行查询,供应商负责对静态 XML 文档或者各种类型的关系数据库执行查询。需要检查 DataDirect 以及数据库供应商的文档,确定您的数据库是否支持 XQuery。



如果熟悉 JDBC 或者编写过 n-层数据驱动的应用程序,您可能已经对数据源的概念非常熟悉了。在这里,数据源就是一个连接对象,如何连接以及连接到哪里都被抽象化了。因此,数据源可能是到 MySQL 数据库的网络连接,也可能是到静态 XML 文档的基于文件的连接。一旦建立了数据源,就可以操作它而不用关心连接的语义了。

如果只需要查询本地磁盘上的 XML 文档(也是本文的重点),连接的设置非常简单。清单 3 中的简单 Java 程序建立了可以查询的数据源。

3. 建立查询数据源

在项目里新建一个class,XQueryTester
package xqj;
import com.ddtek.xquery3.XQConnection;import com.ddtek.xquery3.XQException;import com.ddtek.xquery3.xqj.DDXQDataSource;
public class XQueryTester {
// Filename for XML document to query private String filename;
// Data Source for querying private DDXQDataSource dataSource;
// Connection for querying private XQConnection conn;
public XQueryTester(String filename) {   this.filename = filename; }
public void init() throws XQException {   dataSource = new DDXQDataSource();   conn = dataSource.getConnection(); }
public static void main(String[] args) {   if (args.length != 1) {    System.err.println("Usage: java xqj.XQueryTester [XML filename]");    System.exit(-1);   }
   try {    String xmlFilename = args[0];    XQueryTester tester = new XQueryTester(xmlFilename);    tester.init();   } catch (Exception e) {    e.printStackTrace(System.err);    System.err.println(e.getMessage());   } }}



看起来很长和复杂。主要是因为该测试程序按照非常模块化的方法编写 — 使用构造函数 init() 方法 — 以便不需要很大修改就能用于您自己的程序。

该程序取得文件名(从命令行获得并传递给类的构造函数),然后执行下面的代码:

dataSource = new DDXQDataSource();
conn = dataSource.getConnection();



首先建立一个新的数据源,该对象的类型是 com.ddtek.xquery3.xqj.DDXQDataSource。由于没有连接到数据库,不需要其他配置,因此使用了空构造函数。然后使用数据源得到新的 com.ddtek.xquery3.XQConnection 对象。该对象对于建立和执行新的 XQuery 表达式非常重要,虽然现在还不能执行这些功能,但是可以接受查询字符串并执行了。

查询真正的 XML 文档

还需要一个进行实际查询的 XML 文件。下载 小节包含一个压缩的 CD 目录文件,W3C 提供这个 XML 文档就是为了作为例子。该文件有 200 多行,这里不再列出来了,对于本文中的查询足够了。

cd_catalog.xml 的一部分



Bob Dylan
USA
Columbia
10.90
1985



Bonnie Tyler
UK
CBS Records
9.90
1988





建立 XQuery

接下来需要创建实际查询。使用 Java String 就能做到。创建一个新变量保存查询字符串,如下面的 XQueryTester 类所示(这些代码在 main() 方法中):

try {
String xmlFilename = "src/cd_catalog.xml";
XQueryTester tester = new XQueryTester(xmlFilename);
tester.init();

final String sep = System.getProperty("line.separator");
String queryString =
" for $cd in doc($docName)/CATALOG/CD " +
" where $cd/YEAR > 1980 " +
" and $cd/COUNTRY = 'USA' " +
" order by $cd/YEAR " +
" return " +
"" +
" {$cd/YEAR/text()}";
System.out.println(tester.query(queryString));
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println(e.getMessage());
}


查询选择 1981 年以后的所有采用 US 格式的 CD,按照发行年份排列,返回包含每张 CD 标题和年份的 XML。有几个地方需要注意:







返回的不是结果集中每个节点的值,而是一个 XML 字符串。XML 可以放入另外一个更大的 XML 文档、在线显示或者传递给 XSL 处理程序。
源文档中的 XML 元素名 — CD、TITLE、YEAR 等 — 在结果集中都不见了,改用新的 XML 元素名:cd、title 和 year。
这些查询本身都很简单,只不过从另一个方面证明了 XQuery 从 XML 选择和返回数据的灵活性。

值得一提的是,如果结果集返回 XML 字符串,应该用花括号将返回字符串中的变量包围起来:

return " +
" {$cd/YEAR/text()}"



花括号告诉 XQuery 处理程序要将包围起来的数据作为需要求值和替换的变量而不是文字文本。

声明外部变量

XQuery 使用变量 $docName 表示文档。但是需要显式声明该变量并告诉查询外部程序 — 这里就是 Java 程序 — 将定义该变量。在 XQuery 中需要使用 declare 语法。declare 语法格式如下:

declare variable [variable-name] as [variable-type] external;



该例中的 [variable-name] 即 $docName。[variable-type] 应该是 XML Schema 基本数据类型。多数时候,字符串使用 xs:string,整数使用 xs:int。还有其他几种类型,但这两种最常用。

因此对于 XQueryTester 类需要修改查询:

try {
String xmlFilename = "src/cd_catalog.xml";
XQueryTester tester = new XQueryTester(xmlFilename);
tester.init();

final String sep = System.getProperty("line.separator");
String queryString =
"declare variable $docName as xs:string external;" + sep +
" for $cd in doc($docName)/CATALOG/CD " +
" where $cd/YEAR > 1980 " +
" and $cd/COUNTRY = 'USA' " +
" order by $cd/YEAR " +
" return " +
"" +
" {$cd/YEAR/text()}";
System.out.println(tester.query(queryString));
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println(e.getMessage());
}



现在只需要编写一个执行查询的函数。

运行 XQuery

运行查询需要经过以下步骤:

从 XQConnection 创建一个 XQExpression 对象。
使用 XQExpression 对象的 bindXXX() 方法把变量绑定到查询。
执行查询,结果保存到 XQSequence 对象中。
这些步骤中只有绑定变量需要一些技巧。该例中的变量 docName 需要和传递给程序的文件名联系起来。绑定字符串变量需要使用 bindString。该方法有三个参数:

javax.xml.namespace.QName 实例(JAXP 包中的一个类)和 XQuery 中的变量名
绑定到变量的值
变量类型应该匹配的原子类型
结合起来得到的方法应该是:

public String query(String queryString) throws XQException {
XQExpression expression = conn.createExpression();
expression.bindString(new QName("docName"), filename,
conn.createAtomicType(XQItemType.XQBASETYPE_STRING));
XQSequence results = expression.executeQuery(queryString);
return results.getSequenceAsString(new Properties());
}



第一行 XQExpression expression = conn.createExpression(); 建立了一个新的表达式对象。然后,查询的文档文件名绑定到 docName 变量:expression.bindString(new QName("docName"), filename, conn.createAtomicType(XQItemType.XQBASETYPE_STRING));。现在不用考虑 QName 对象的机制,只需要把 XQuery 中的变量的名称(没有 $ 字符)赋给它即可。下一个参数是文件名;第三个是一个非常固定的值,要求数值所符合的类型。由于查询中变量被定义为 xs:string,因此需要 XQItemType.XQBASETYPE_STRING 类型。

虽然有些代码不够直观,大部分只要查看 API 文档就明白了。其他 bindXXX() 方法如 bindInt()、bindFloat() 等等,都是相同的原理。

最后执行查询并返回结果序列。可以迭代结果集,或者直接将其转化成字符串让程序处理。query() 方法就是这么做的,因而不需要调用程序了解 DataDirect XQuery API。

分享到:
评论
1 楼 dolphin0618 2012-07-24  
这例子能给个下载么,我想打包

相关推荐

    用XML、XQuery和XML数据库技术加速SOA

    比如,最早提出用SOA实现ebXML的GeneralMotorsCorp.,其最初的设计使用的是UniversalBusinessLanguage(UBL),建立的XML消息有150,000字节到10兆字节甚至更大。2004年,我的性能测试公司PushToTest认为当时的Java?...

    论文研究-基于BaseX数据库的OWL本体存储查询研究.pdf

    利用BaseX的查询接口和XQuery查询语言对OWL本体进行检索,在建立推理规则库基础上,实现本体查询扩展与推理。实验将提出的存储查询方法与基于关系型数据库的存储查询方法进行对比,验证了提出的方法具备高效的存储...

    sql学习的 学习心得

    XQuery确实不错,但是个人对其没好感。(CSDN的开发者应 该是相当的熟了!) 2、外键的级联更能扩展 可能大部分的同行在设计OLTP系统的时候都不愿意建立外键,都是通过程序来控制父子数据的完整性。但是 再开发...

    XMLSpy2013.7z

    增加编辑的流畅性,在软件中,您不仅可以编辑XML文本,还能使用XSLT和XQuery处理XML文档,让您在编辑的过程中可以快速完成字体的处理;xmlspy2013可以创建表单、创建处理程序、创建宏,帮助您建立安全、稳定的脚本...

    基于云存储的XML隐私保护模型(云存储端)论文

    2.3.2 XQuery 第三章 现有的XML隐私保护技术 3.1 访问控制技术 3.1.1 自主访问控制。 3.1.2 强制访问控制 3.1.3 基于角色的访问控制 3.2 加密技术 3.2.1 常用的对称加密算法 3.2.2 常用的非对称加密算法 第...

    XML数据库的加密与密文检索 (2010年)

    在此基础上建立了 XQuery检索翻译器,该翻译器支持数值范围检索,且只需解密少数密文,可提高检索效率,并证明加密模型具备足 够的安全性。以 Oracle XML DB为例进行实验的结果显示,密文检索效率达到无索引明文检索的65%...

    解析SQLServer任意列之间的聚合

    ——————————————————————————–/* 测试名称:利用 XML 求任意列之间的聚合 测试功能:对一张表的列数据做 min 、 max 、 sum 和 avg 运算 运行原理:字段合并为 xml 后做 xquery 查询转为...

    XPath2.Net:.NET的轻量级XPath2

    基于开发XQuery的实践而给出的实现完全符合规范要求。 项目是从分叉的 建立 质量 建立Azure CodeFactor 声纳质量门 声纳虫 声纳代码气味 声纳覆盖 Codecov NuGet XPath2 XPath2.Extensions MyGet(预览...

    扩展的XML树模式匹配:理论和算法

    但是,XML查询语言(例如XPath和XQuery)定义了更多的轴和功能,例如取反功能,基于订单的轴和通配符。 在本文中,我们研究了一大套XML树模式,称为扩展XML树模式,其中可能包括PC,AD关系,取反函数,通配符和顺序...

    sql2005全文检索.doc

     首先, 让我们建立检索表的全文检索,全文检索要求唯一索引,故需要在相关表建立唯一聚集索引。  第二步,使用SQL DDL或者SQL Server Management Studio建立表的全文检索。  1)使数据库支持全文检索。   图...

    photoman:基于 MarkLogic Server 构建的在线照片管理系统

    照片管理器这个项目是一个建立在之上的照片管理应用程序。 (它使用外部二进制文件,因此移植到 4.x 是不切实际的。)您可以在看到它的运行情况。亚马逊 S3 注意:为了解决一些带宽问题,我最近实施了一个分支“s3”...

    tei-digital-age:Tufts 2012 年 NEH 研究所的示例代码在数字时代处理文本

    建立标记指南和最佳实践。 使用内联注释与隔离标记。 处理重叠的层次结构。 OAC(开放注释协作) 利用注释工具。 应用关联数据概念。 分发格式:优化显示与启用数据重用。 数据 我们为练习选择了两份样本文本...

    Banksy:Banksy,KML,数字人文科学

    该项目的目标是为他的作品建立一个数据库,对作品的位置进行地理标记,并创建时间表。 我们旨在使用KML(钥匙Kong标记语言)创建一个覆盖图,以精确定位Banksy留下标签的每个位置。 我们还将通过查看他在某个国家/...

    dashboard:eXist-db仪表板

    Bower建立在nodejs堆栈的基础上,因此需要安装nodejs才能正常工作。 通常,当使用依赖工具时,依赖模块是从远程存储库动态加载的。 这当然具有优势,但是当源由于某种原因而变得不可用时,也会带来无法检测到的深...

    db2数据库入门教程(官方中文版)

    PART I – 概览.........................................................................................................................11 第 1章 – DB2 Express-C是什么?..................................

    db2数据库入门官方教程(中文版)

    资源简介 第 1章 – DB2 Express-C是什么?..........................................................................................13 1.1免费开发、部署和分发… 无限制!....................................

Global site tag (gtag.js) - Google Analytics