论坛首页 入门技术论坛

编写简单的XPath程序

浏览 9013 次
精华帖 (1) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2008-01-05  

当前使用XPath 1.0


1,需求说明
假设要查询一个图书列表,寻找TEST的著作.

2,创建项目
创建一个Java项目.

Java 1.5推出了javax.xml.xpath包,提供一个引擎和对象模型独立的XPath库.只要Java环境>1.5,无需增加类库.

这个包也可用于Java 1.3及以后的版本,但需要单独安装Java API for XML Processing(JAXP)1.3

提示:Xalan 2.7 和Saxon 8 以及其他产品包含了这个库的实现.

3,创建包含图书信息的XML文档
编写包含图书信息的XML文档,将其命名为books.xml,并将其放至在src目录下:

<inventory>
        <book year="2000">
                <title>Thinking in Java</title>
                <author>TEST</author>
                <publisher>JQGYCBS</publisher>
                <isbn>80958</isbn>
                <price>98.95</price>
        </book>

        <book year="2005">
                <title>ROR</title>
                <author>TEST</author>
                <publisher>DZGYCBS</publisher>
                <isbn>0743416910</isbn>
                <price>65.99</price>
        </book>

        <book year="1995">
                <title>H</title>
                <author>King</author>
                <publisher>Sc</publisher>
                <isbn>0553862</isbn>
                <price>77.50</price>
        </book>
</inventory>


4,XPath表达式的使用介绍
查找所有图书的 XPath 查询非常简单:

//book[author="TEST"]
 book代表节点的名称,author属性的名称,后面是要查询的值


为了找出这些图书的标题(title),只要增加一步,表达式就变成了:

//book[author="TEST"]/title
 title代表要取元素的名称


最后,真正需要的是 title 元素的文本节点内容.这就要求再增加一步,完整的表达式就是:

//book[author="TEST"]/title/text()
 text()该节点的内容



5,编写代码
现在提供一个简单的程序,它从 Java 语言中执行以上的表达式查询,然后把找到的所有图书的标题打印出来.

5.1,将XML文档加载到DOM Document对象中
首先,需要将文档加载到一个 DOM Document 对象中.

下面的简单代码片段解析文档并建立对应的 Document 对象:

//用 JAXP 解析文档
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// never forget this!
factory.setNamespaceAware(true);
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("src/books.xml");



到目前为止,这仅仅是标准的 JAXP 和 DOM.

5.2,创建 XPathFactory

XPathFactory pathFactory = XPathFactory.newInstance();


XPathFactory说明:

XPathFactory是一个抽象工厂.

抽象工厂设计模式使得这一种 API 能够支持不同的对象模型,如 DOM、JDOM 和 XOM.

为了选择不同的模型,需要向XPathFactory.newInstance()方法传递标识对象模型的统一资源标识符(URI).

比如 http://xom.nu/ 可以选择 XOM.但实际上,到目前为止
DOM 是该 API 支持的惟一对象模型.

5.3,使用XPathFactory工厂创建 XPath 对象

XPath xpath = pathFactory.newXPath();



5.4,使用XPath对象编译XPath表达式

XPathExpression pathExpression = xpath.compile("//book[author='TEST']/title/text()");



5.5,计算 XPath 表达式得到结果
表达式是针对特定的上下文节点计算的,在这个例子中是整个文档.这时还必须指定返回类型.这里要求返回一个节点集:

Object result = pathExpression.evaluate(doc, XPathConstants.NODESET);
//doc是Document对象名,XPathConstants代表XPath常量,NODESET是XPath 1.0 NodeSet数据类型
//XPathConstants.NODESET将XPathConstants常量返回NODESET类型



说明:
多数 XPath 表达式,特别是位置路径,都返回节点集.

但是还有其他可能:


比如,XPath 表达式:count(//book) 返回文档中的图书数量.
XPath 表达式:count(//book[author="TEST"]) > 10 返回一个布尔值:如果文档中 TEST的著作超过 10 本则返回 true,否则返回 false.



evaluate() 方法被声明为返回 Object,实际返回什么依赖于 XPath 表达式的结果以及要求的类型

一般来说,XPath与Java的映射关系是:


number 映射为 java.lang.Double
string 映射为 java.lang.String
boolean 映射为 java.lang.Boolean
node-set 映射为 org.w3c.dom.NodeList


在 Java 中计算 XPath 表达式时,第二个参数(XPathConstants常量)指定需要的返回类型.有五种可能,都在 javax.xml.xpath.XPathConstants 类中命名了常量:

XPathConstants.NODESET
XPathConstants.BOOLEAN
XPathConstants.NUMBER
XPathConstants.STRING
XPathConstants.NODE

XPathConstants.NODE提示:

最后一个 XPathConstants.NODE 实际上没有匹配的 XPath 类型.只有知道 XPath 表达式只返回一个节点或者只需要一个节点时才使用它.如果 XPath 表达式返回了多个节点并且指定了 XPathConstants.NODE,则 evaluate() 按照文档顺序返回第一个节点.如果 XPath 表达式选择了一个空集并指定了 XPathConstants.NODE,则 evaluate() 返回 null.



注意:如果不能完成要求的转换,evaluate()将抛出 XPathException.

5.6,将结果强制转化成 DOM NodeList
通过将结果强制转化成 DOM NodeList,然后遍历列表就能得到所有的标题:

NodeList nodes = (NodeList) result;
        for (int i = 0; i < nodes.getLength(); i++) {
                System.out.println(nodes.item(i).getNodeValue());
        }



6,完整Java程序代码

package book;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NodeList;

public class Test {
        public static void main(String[] args) throws Exception {
                DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                factory.setNamespaceAware(true); // never forget this!
                DocumentBuilder builder = factory.newDocumentBuilder();
                Document doc = builder.parse("src/books.xml");

                XPathFactory pathFactory = XPathFactory.newInstance();

                XPath xpath = pathFactory.newXPath();

                XPathExpression pathExpression = xpath
                                .compile("//book[author='TEST']/title/text()");

                Object result = pathExpression.evaluate(doc, XPathConstants.NODESET);

                NodeList nodes = (NodeList) result;
                for (int i = 0; i < nodes.getLength(); i++) {
                        System.out.println(nodes.item(i).getNodeValue());
                }
        }
}

 

   发表时间:2008-01-05  
详细看下先
0 请登录后投票
   发表时间:2008-01-29  
貌似抄袭IBM development网站的内容:
http://www.ibm.com/developerworks/cn/xml/x-javaxpathapi.html
0 请登录后投票
   发表时间:2008-01-31  
本人承认,该技术来源于IBM Development,该blog是我的技术总结.谢谢支持!
2 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics