在Java环境中使用 XQuery
来源:ibm 发布时间:2008-07-24 收藏 投稿 字体:【大 中 小】
将 XQJ JAR 添加到类路径
现在需要修改类路径,使其包含 XQuery JAR 和存储在 lib 目录下 ddxq.jar 中的 XQJ 类。这不是 原来下载的 JAR,而是在上面解压过程中由 JAR 安装的(如果 DataDirect 采用 ZIP 或 .tar.gz 压缩文件可能就不那么容易混淆了)。可以手工设置类路径,也可使用 shell 脚本、.profile 文件或者使用 IDE 将 JAR 添加到类路径中。要保证类路径中能够访问到 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. 建立查询数据源
package ibm.dw.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 ibm.dw.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 多行,这里不再列出来了,对于本文中的查询足够了。
清单 4 显示了该文档的一小部分,以便您能了解其结构。
清单 4. cd_catalog.xml 的一部分
<?xml version="1.0" encoding="ISO-8859-1"?>
<CATALOG>
<CD>
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>10.90</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<!-- more CD listings ... -->
</CATALOG>
建立 XQuery
接下来需要创建实际查询。使用 Java String 就能做到。创建一个新变量保存查询字符串,如下面的 XQueryTester 类所示(这些代码在 main() 方法中):
try {
String xmlFilename = args[0];
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><title>{$cd/TITLE/text()}</title>" +
" <year>{$cd/YEAR/text()}</year></cd>";
System.out.println(tester.query(queryString));
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println(e.getMessage());
}
查询选择 1981 年以后的所有采用 US 格式的 CD,按照发行年份排列,返回包含每张 CD 标题和年份的 XML。有几个地方需要注意:
docName 变量表示要搜索的文档。代码需要使用由命令行传递给程序的文档来填充该变量。
返回的不是结果集中每个节点的值,而是一个 XML 字符串。XML 可以放入另外一个更大的 XML 文档、在线显示或者传递给 XSL 处理程序。
源文档中的 XML 元素名 — CD、TITLE、YEAR 等 — 在结果集中都不见了,改用新的 XML 元素名:cd、title 和 year。
这些查询本身都很简单,只不过从另一个方面证明了 XQuery 从 XML 选择和返回数据的灵活性。
值得一提的是,如果结果集返回 XML 字符串,应该用花括号将返回字符串中的变量包围起来:
return <cd><title>{$cd/TITLE/text()}</title>" +
" <year>{$cd/YEAR/text()}</year></cd>"
花括号告诉 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 = args[0];
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><title>{$cd/TITLE/text()}</title>" +
" <year>{$cd/YEAR/text()}</year></cd>";
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。
清单 5 显示了完整的 XQueryTester 代码。
清单 5. 完整的 XQueryTester 类
package ibm.dw.xqj;
import javax.xml.namespace.QName;
import java.util.Properties;
import com.ddtek.xquery3.XQConnection;
import com.ddtek.xquery3.XQException;
import com.ddtek.xquery3.XQExpression;
import com.ddtek.xquery3.XQItemType;
import com.ddtek.xquery3.XQSequence;
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 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());
}
public static void main(String[] args) {
if (args.length != 1) {
System.err.println("Usage: java ibm.dw.xqj.XQueryTester [XML filename]");
System.exit(-1);
}
try {
String xmlFilename = args[0];
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><title>{$cd/TITLE/text()}</title>" +
" <year>{$cd/YEAR/text()}</year></cd>";
System.out.println(tester.query(queryString));
} catch (Exception e) {
e.printStackTrace(System.err);
System.err.println(e.getMessage());
}
}
}
运行 XQueryTester
编译该程序并运行:
[bdm0509:~/Documents/developerworks/java_xquery]
java ibm.dw.xqj.XQueryTester cd_catalog.xml
<cd><title>Greatest Hits</title><year>1982</year></cd><cd><title>
Empire Burlesque</title><year>1985</year></cd><cd><title>When a man loves a woman
</title><year>1987</year></cd><cd><title>The dock of the bay</title><year>
1987</year></cd><cd><title>Unchain my heart</title><year>1987</year></cd>
<cd><title>Big Willie style</title><year>1997</year></cd><cd><title>
1999 Grammy Nominees</title><year>1999</year></cd>
注意:为了适应在线文章的格式插入了分行符。实际的结果没有断行,而是连成一行。
实验!
该程序能够处理查询和绑定到 XML 文档。现在可以尝试不同的查询字符串,体会 XQuery 和从 Java 程序中运行这些查询。尝试选择所有的唱片,将返回结果的格式改为格式化文本。看看如何返回所有的唱片,从最新的到最老的,或者价格低于 10 美元的所有唱片。有了这样的程序后,很容易就能修改查询以便进行试验,甚至改变提供给程序的 XML 文档。
结束语
不了解 XQuery 就很难讨论 XQJ,不熟悉 XPath 就很难讨论 XQuery。将这些不同的部分结合起来通常意味着仅仅处理其中的一部分 — Java 程序执行查询,或者开始查询的文档中的位置 — 非常简单。这恰恰也是在 Java 中使用 XQuery 的最佳途径:这些简单的、独立的部分结合起来能够组成强大的程序。
由于必须熟悉多种不同的技术,尝试一个方面的时候应该保持其他两个方面不变。先保持 Java 程序不变,尝试不同的查询和不同的输入文档吧。然后从一个简单的查询开始,尝试在查询中使用更多的输入变量。或者改变返回语句中的 XPath,然后再修改搜索的起点。等这些部分都熟悉了之后,就会发现您的查询更复杂,Java 代码更健壮。
分享到:
相关推荐
delphi XQuery2.rar 万能查询控件
2. **下载说明.txt**:这个文件可能是下载和使用DB2_XQuery.ppt的指南,提供了关于如何打开、查看或打印文件的步骤,也可能包含一些注意事项和使用条款。 3. **A5下载- 更全的站长资源平台.url**:这是一个网页链接...
XML 学习之 XQuery 教程 XQuery 语言是用于查询 XML 数据的语言,等同于 SQL 对数据库的作用。XQuery 被设计用来查询 XML 数据,不仅仅限于 XML 文件,还包括任何可以 XML 形态呈现的数据,包括数据库。 知识点...
### XQuery:一种专为XML数据设计的查询语言 #### 引言 随着互联网技术的发展,数据交换的需求日益增长,而Extensible Markup Language (XML)因其灵活性和自描述性成为了跨应用数据交流的首选格式。XML的独特之处...
XQuery是一种用于处理XML数据的语言,它源自XPath,并在XPath的基础上扩展了更多功能。在本文中,我们将深入探讨XQuery的基本使用语法,包括其特点、变量定义、条件表达式、比较操作以及选择和过滤元素的方法。 ...
2. **FLWOR表达式** FLWOR是XQuery中的一个核心概念,代表“For-Let-Where-Return”。"使用flwor表达式查询和连接.pdf"可能会详细解释如何使用FLWOR表达式进行迭代、过滤和结果组合。例如,`for`子句用于定义迭代,...
根据提供的文件信息,“xquery参考手册.pdf”主要涵盖了关于XQuery在DB2数据库中的应用及其相关的概念和技术细节。以下是对该文档中涉及的关键知识点的详细解释: ### 一、XQuery简介 XQuery是一种用于查询XML数据...
在这个“XQUERY的好例子”中,我们将探讨如何通过四个具体的XQuery文件(dataQ1.xquery、dataQ2.xquery、dataQ3.xquery和dataQ4.xquery)来解析和操作XML数据,例如实验6中的Flights-Dat数据。 首先,让我们理解XML...
XQuery数据查询语言[1-1] XQuery数据查询语言[1-2] XQuery数据查询语言[2-1] XQuery数据查询语言[2-2] XQuery数据查询语言[3-1] XQuery数据查询语言[3-2] XQuery数据查询语言[4]
2. **FLWOR表达式**: FLWOR表达式是XQuery中的核心概念之一,由“for”、“let”、“where”、“order by”和“return”关键字组成。这些关键字允许用户定义复杂的查询逻辑,包括过滤、排序和聚合数据等操作。...
2、理解和掌握XQuery查询计划的基本结构、各种子句的使用、(递归)函数的声明和使用、嵌套查询的使用,能够熟练地利用集成开发环境编写完成各种查询工作的XQuery查询计划,为在主流关系数据库中使用XQuery进行数据...
### XQuery概述与基本概念 #### 一、XQuery简介 XQuery是一种强大的查询语言,专门用于处理XML数据。随着XML被广泛应用于多种场景中,包括网页、消息、书籍、会计数据、数据库表的XML表示、编程接口等,对XML进行...
【XQuery】是一种查询语言,专门用于处理XML数据。它为开发者提供了强大的工具,能够高效地提取、操作和转换XML文档。XQuery的出现源于XML在数据交换和存储中的广泛应用,它简化了处理XML的复杂性,提高了开发效率。...
XQuery经典的学习文档,有很多实例供练习参考
XQuery是一种用于查询XML数据的XML查询语言,适用于处理大量异构的XML数据源,并能够在Web上检索和重构信息。本教程将介绍XQuery的基础知识,包括表达式、类型系统、核心规范、处理模型、类型推理和类型检查,并提供...
2、理解和掌握XQuery查询计划的基本结构、各种子句的使用、(递归)函数的声明和使用、嵌套查询的使用,能够熟练地利用集成开发环境编写完成各种查询工作的XQuery查询计划,为在主流关系数据库中使用XQuery进行数据...
XQuery是一种功能强大的查询语言,专门用于处理XML文档。它被设计用来提取、组合和转换XML数据,类似于SQL对关系数据库的操作。在Java环境中,我们可以使用各种库来执行XQuery查询,例如Saxon、XQJ等。在这个...
### XQuery介绍与应用 #### 一、XQuery概述 XQuery是一种强大的查询语言,用于在XML文档中进行数据检索和处理。它不仅能够选择、提取数据,还支持对数据进行排序、聚合等操作,并且可以将结果转换为新的XML文档...
JSONiq是一种专门针对JSON数据格式的查询语言,其设计理念基于XML的XQuery查询语言。XQuery自从被标准化以来,广泛应用于数据库、数据流处理器、数据集成平台、应用集成平台、XML消息路由软件、Web浏览器插件等多种...