`
berdy
  • 浏览: 508769 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

使用xpath提取xml中的节点信息

阅读更多
    类似于使用SQL从数据库从查询数据。XPath可以方便的在XML 文档中查找信息的语言,并在XML文档中对元素和属性进行遍历。XPath 使用路径表达式来选取 XML 文档中的节点或节点集。节点是通过沿着路径 (path) 或者步 (steps) 来选取的。
    虽然有很强的表达能力,XPath 并不是 Java 语言,事实上 XPath 不是一种完整的编程语言。有很多东西用 XPath 表达不出来,甚至有些查询也无法表达。幸运的是,可以把 XPath 结合到 Java 程序中,这样就能发挥两者的优势了:Java 做 Java 所擅长的,XPath 做 XPath 所擅长的。
    在最初,Java 程序执行 XPath 查询所需要的应用程序编程接口(API)因形形色色的 XPath 引擎而各不相同。Xalan 有一种 API,Saxon 使用另一种,其他引擎则使用其他的 API。这意味着代码往往把您限制到一种产品上。最好能够试验具有不同性能特点的各种引擎,而不会带来不适当的麻烦或者重新编写代码。
    幸运的是Java 5 推出了 javax.xml.xpath 包,提供一个引擎和对象模型独立的 XPath 库。这个包也可用于 Java 1.3 及以后的版本,但需要单独安装 Java API for XML Processing (JAXP) 1.3。Xalan 2.7 和 Saxon 8 以及其他产品包含了这个库的实现。

这里先简单介绍下xpath的基本语法,后面再举详细的例子。节点选取语法:

节点路径表达式:
表达式描述
nodename选取此节点的所有子节点
/从根节点选取
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
.选取当前节点
..选取当前节点的父节点
@选取属性


谓词(用来查找某个特定的节点或者包含某个指定的值的节点,通常使用在[]内)
路径表达式结果
/bookstore/book[1]选取属于 bookstore 子元素的第一个 book 元素。
/bookstore/book[last()]选取属于 bookstore 子元素的最后一个 book 元素。
/bookstore/book[last()-1]选取属于 bookstore 子元素的倒数第二个 book 元素。
/bookstore/book[position()<3]选取最前面的两个属于 bookstore 元素的子元素的 book 元素。
//title[@lang]选取所有拥有名为 lang 的属性的 title 元素。
//title[@lang='eng']选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性。
/bookstore/book[price>35.00]选取所有 bookstore 元素的 book 元素,且其中的 price 元素的值须大于 35.00。
/bookstore/book[price>35.00]/title选取所有 bookstore 元素中的 book 元素的 title 元素,且其中的 price 元素的值须大于 35.00。

节点通配符:
通配符描述
*匹配任何元素节点
@*匹配任何属性节点
node()匹配任何类型的节点

路径组合表达式,组合多个路径表达式,扩大选择范围;例如:
//book/title | //book/price 选取所有 book 元素的 title 和 price 元素。

另外,关于xpath的轴和运算符这里就不再细说了,有兴趣的可以参看后面的参看资料。
下面给出一个实例,展示如何在java中使用xpath提取xml中的信息
xml文件test.xml的内容:
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
	<book category="COOKING">
		<title lang="en">Everyday Italian</title>
		<author>Giada De Laurentiis</author>
		<year>2005</year>
		<price>30.00</price>
	</book>
	<book category="CHILDREN">
		<title lang="en">Harry Potter</title>
		<author>J K. Rowling</author>
		<year>2005</year>
		<price>29.99</price>
	</book>
	<book category="WEB">
		<title lang="en">XQuery Kick Start</title>
		<author>James McGovern</author>
		<author>Per Bothner</author>
		<author>Kurt Cagle</author>
		<author>James Linn</author>
		<author>Vaidyanathan Nagarajan</author>
		<year>2003</year>
		<price>49.99</price>
	</book>
	<book category="WEB">
		<title lang="zh">Learning XML</title>
		<author>Erik T. Ray</author>
		<year>2003</year>
		<price>39.95</price>
	</book>
</bookstore>

提取xml文件中节点信息的java代码:
/**
 * "/"表示绝对路径 <br/>
 * "/AA" 所有根节点AA<br/>
 * "/AA/BB" 所有根节点下的所有BB节点<br/>
 * 
 * "//" 表示相对路径<br/>
 * "//BBB" 表示所有的名字为BBB的节点<br/>
 * "//DDD/BBB" 表示所有父节点为DDD的BBB节点<br/>
 * 
 * "*" 表示选择所有由星号之前的路径所定位的元素<br/>
 * "/AAA/CCC/DDD/*" 选择所有路径依附于/AAA/CCC/DDD的元素<br/>
 * "//*" 选择所有元素
 * 
 * "/AAA/BBB[1]" 选择AAA的第一个BBB子元素<br/>
 * "/AAA/BBB[last()]" 选择AAA的最后一个BBB子元素<br/>
 * 
 * "//@id" 选择所有的id属性<br/>
 * "//BBB[@id]" 选择有id属性的BBB元素<br/>
 * "//BBB[@name]" 选择有name属性的BBB元素<br/>
 * "//BBB[@*]" 选择有任意属性的BBB元素<br/>
 * "//BBB[not(@*)]" 选择没有属性的BBB元素<br/>
 * 
 * "//BBB[@id='b1']" 选择含有属性id且其值为'b1'的BBB元素<br/>
 * "//BBB[@name='bbb']" 选择含有属性name且其值为'bbb'的BBB元素<br/>
 * "//BBB[normalize-space(@name)='bbb']"
 * 选择含有属性name且其值(在用normalize-space函数去掉前后空格后)为'bbb'的BBB元素<br/>
 * 
 * "//*[count(BBB)=2]" 选择含有2个BBB子元素的元素<br/>
 * "//*[count(*)=2]" 选择含有2个子元素的元素<br/>
 * "//*[name()='BBB']" 选择所有名称为BBB的元素(这里等价于//BBB)<br/>
 * "//*[starts-with(name(),'B')]" 选择所有名称以"B"起始的元素<br/>
 * "//*[contains(name(),'C')]" 选择所有名称包含"C"的元素<br/>
 * 
 * "//CCC | //BBB" 选择所有的CCC和BBB元素<br/>
 * "/AAA/EEE | //BBB" 选择所有的BBB元素和所有是AAA的子元素的EEE元素<br/>
 */

InputSource inputSource = new InputSource(new FileInputStream("test.xml"));
XPathFactory factory = XPathFactory.newInstance();
XPath xPath = factory.newXPath();
XPathExpression expression = xPath.compile("//book/title[@lang=\"en\"]");
NodeList list = (NodeList) expression.evaluate(inputSource, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
	Node node = list.item(i);
	System.out.println(node.getNodeName());
}

解析的步骤如下:
1、获取xml文件
InputSource inputSource = new InputSource(new FileInputStream("test.xml"));
//或者使用DOM解析
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse("test.xml");

2、接下来创建 XPathFactory:
XPathFactory factory = XPathFactory.newInstance();

3、然后使用这个工厂创建 XPath 对象:
XPath xPath = factory.newXPath();

4、使用XPath 对象编译 XPath 表达式:
XPathExpression expression = xPath.compile("//book/title[@lang=\"en\"]");

5、使用表达式的evaluate(),并处理结果:
NodeList list = (NodeList) expression.evaluate(inputSource, XPathConstants.NODESET);
for (int i = 0; i < list.getLength(); i++) {
	Node node = list.item(i);
	System.out.println(node.getNodeName());
}

evaluate() 方法被声明为返回 Object。实际返回什么依赖于 XPath 表达式的结果以及要求的类型。一般来说,XPath 的
number 映射为 java.lang.Double
string 映射为 java.lang.String
boolean 映射为 java.lang.Boolean
node-set 映射为 org.w3c.dom.NodeList

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

    在使用xpath解析xml的时候还有很多需要注意的地方,若 XML 文档中的元素在名称空间中,查询该文档的 XPath 表达式必须使用相同的名称空间。XPath 表达式不一定要使用相同的前缀,只需要名称空间 URI 相同即可。事实上,如果 XML 文档使用默认名称空间,那么尽管目标文档没有使用前缀,XPath 表达式也必须使用前缀。另外我们也还可以在java中扩展xpath的函数。更多信息请参看下面的参考资料。

参考资料:
Java 语言的 XPath API
Working XML: Get started with XPath 2.0
XPath 教程


1
0
分享到:
评论

相关推荐

    用XPath 表达式从 XML 文档中提取信息

    NULL 博文链接:https://huibin.iteye.com/blog/902913

    XMLNode:MATLAB 类,允许您使用 XPath 从 XML 文档中导航和提取数据。-matlab开发

    此对象允许您使用 XPath 查询从 XML 文档中导航和提取数据。 例如,在颜色的 XML 文档(colors.xml)中&lt;颜色&gt; &lt;颜色&gt; 红色&lt;/name&gt; &lt;hex&gt;FF0000&lt;/hex&gt; &lt;/颜色&gt; &lt;颜色&gt; 绿色&lt;/name&gt; &lt;hex&gt;00FF00&lt;/hex&gt; &...

    Task 02 Xpath(2.2)

    2.2 学习xpath 2.2.1 学习目标: 学习xpath,使用lxml+xpath提取内容。 使用xpath提取丁香园论坛的回复内容。 ... 2.2.2 Xpath常用的路径表达式: ...XPath使用路径表达式在XML文档中选取节点。节点是通过沿

    Python Selenium 获取动态网页指定元素的超链接.pdf

    Lxml是XML和HTML的解析器,其主要功能是解析和提取XML和HTML中的数据;lxml和正则一样,也是用C语言实现的,是一款高性能的python HTML、XML解析器,也可以利用XPath语法,来定位特定的元素及节点信息。 XPath 是...

    php实现解析xml并生成sql语句的方法

    今天遇到一个需求:将某个xml中的节点属性提取出来,然后更新数据库某一表中的字段。 思路: 解析XML,获取所有的节点属性 –&gt; 循环节点集合,获取对应的属性 –&gt; 拼接sql字符串存入一数组 –&gt; 将数组转为字符串保存...

    XQuery权威指南(简码·扫描版)

     本书比较深入全面地介绍了XQuery相关知识,包括XQuery的概述和快速指南,如何使用XQuery编写简单和复杂的查询,如何对XML数据过滤、排序和分组,还讲述了FLWOR表达式、XPath及提取、组合数据的XQuery工具。...

    xml_fiddler:用于处理XML文档的工具

    它可以对折叠节点进行分组,单击以复制xpath并从节点中提取值。 它可能不适用于太大的文件,但这不是目标。 笔记 贡献 在GitHub上( 欢迎报告错误和请求请求。 执照 根据的条款,该东西可以作为开源使用。

    5.1.0-Crx4Chrome.com.crx

    chrom 浏览器的插件,用于分析XML或HTML的结构,并通过xpath语法提取报需的节点。使用方法:F12 -&gt; elements , 然后在右侧的面板中点击更多(》),选择chropath

    2.ASP.NET.2.0.高级编程(第4版) [1/7]

    13.2.3 从XML中提取.NET CLR类型 431 13.2.4 ReadSubtree和XmlSerialization 433 13.2.5 用XmlWriter创建XML 435 13.2.6 2.0版本中XmlReader和XmlWriter的改进 437 13.3 XmlDocument和XPathDocument 438 13.3.1...

    合并PDF软件.rar

    替换字库:替换文档中使用的字体库;嵌入字库到PDF文档,消除复制文本时的乱码,使之可在没有字库的设备(如Kindle等电子书阅读器)上阅读。 分析文档结构:以树视图显示PDF文档结构,可编辑修改PDF文档节点,或将...

    快速入门网络爬虫系列 Chapter08 | 使用Python库抽取

    使用Python库抽取一、基础知识点1、Xpath2、DOM树二、信息抽取1、lxml1.1、使用HTML()函数进行文本读取1、获取网页中的所有链接(绝对链接和相对链接)2、获取网页内部所指向的链接3、获取网页内的文字2、...

    ASP.NET2.0高级编程(第4版)1/6

     程序中使用预编译  的业务对象880 24.2 COM交互操作性:在.NET 中使用COM881 24.2.1 运行库可  调用包装(RCW)881 24.2.2 在ASP.NET代码中  使用COM对象882 24.2.3 错误处理887 24.2.4 用.NET应用程序  部署COM...

    PDF补丁丁( PDFPatcher.)

    PDF补丁丁是一个用于修改PDF文件信息的... 分析文档结构:以树视图显示PDF文档结构,可编辑修改PDF文档节点,或将PDF文档导出成XML文件,供PDF爱好者分析、调试之用。 永久免费,绝不过期,无广告,无弹出废话对话框。

    asp.net知识库

    在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+总结 [ADO.NET]由数据库触发器引发的问题 为ASP.NET封装的SQL数据库...

    快学 scala 中文版 带完整目录

    16.5 在属性中使用表达式 264 16.6 特殊节点类型 265 16.7 类XPath表达式 266 16.8 模式匹配 267 16.9 修改元素和属性 268 16.10 XML变换 269 16.11 加载和保存 270 16.12 命名空间 273 练习 275 第17章 ...

    n-gram-开源

    N-GRAM-用于从xml文件提取n-gram的工具主要功能:(i)XPath表达式,用于节点选择和停止模式识别; (ii)自定义xsl样式表以过滤n-gram数据。

Global site tag (gtag.js) - Google Analytics