`
m635674608
  • 浏览: 4924415 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

利用 XPath-jQuery 集锦手册在 XPath 和 jQuery 之间做选择

    博客分类:
  • js
 
阅读更多

如果您正在 XML 应用程序中使用 XPath,但是却需要对 Web 应用程序使用 jQuery,那会怎么样呢?如果您知道 jQuery,却需要在应用程序中使用 XPath,又会如何呢?使用这个方便的集锦手册(phrase book),从知道的转向需要知道的。在本文中,学习使用 XPath 1.0 和 jQuery 1.4 处理类似的任务,让您能够在必要的时候从其中一个快速转向另一个。

Chris Herborth, 技术作家兼软件开发人员, Freelance

2010 年 4 月 19 日

  • +内容

简介

XML 是一种受到良好支持的 Internet 标准,使用它编码的结构化数据很容易被几乎任何编程语言解码,甚至能够被人类阅读或编写,只要他们使用标准文本编辑器即可。很多应用程序,尤其是现代的标准兼容的 Web 浏览器,都可以直接处理 XML 数据。

常用缩写词

  • Ajax:异步 JavaScript + XML
  • API:应用程序编程接口
  • DOM:文档对象模型
  • W3C:万维网联盟
  • XHTML:可扩展超文本标记语言
  • XML:可扩展标记语言
  • XSLT:可扩展样式表语言转换

XPath(XML Path 语言)是一种强大的查询语言,用于选择 XML 文档中的节点。XPath 标准的 1.0 版本广泛实现于各种语言,比如 Java™、C# 和 JavaScript。

jQuery 是一种事实上标准的跨浏览器 JavaScript 库,用于选择和操纵 XHTML 文档(以及通过 Ajax 加载的 XML 文档)中的节点。它已经被很多大公司(包括 Google、IBM®、Microsoft® 和 Twitter)采用。在我写作本文时,发布了它的当前版本 1.4;所以我马上进行了升级,以利用它所承诺的更快速度。注意,本文中的 jQuery 例子应该未加修改地使用前一版本,即 jQuery 1.3.2。

 

为何在 XPath 存在于 JavaScript 中时使用 jQuery?

如果 XPath 是 W3C 标准,并且实现于 JavaScript 中,那么为什么还要麻烦地使用 jQuery 呢?

XPath 是一个普通的 XML 标准,而 jQuery 是一个轻量级的库,设计用于处理跨浏览器兼容性方面的问题,使您不必担心用户运行的是哪种浏览器。它足够灵活,可以在使用标准 JavaScript 词汇的浏览器 DOM 中工作,它还提供一些大大简化 Web 应用程序开发的附加特性,比如强大的 Ajax 和动画支持。

但是,应该总是对手边的工作使用适当的工具;更多地了解这两个工具无疑有助于您为下一个项目挑选适当的技术。

 

例子

整篇文章中,都会回过头来参考一个方便的样例 XML 文档,参见 清单 1。此书籍列表包括各种信息,比如作者、两种完全虚构的价格和书名。

清单 1. 样例 XML 文档 (book.xml)
<?xml version="1.0" encoding="utf-8"?>
<catalog>
    <book format="trade">
        <name>Jennifer Government</name>
        <author>Max Barry</author>
        <price curr="CAD">15.00</price>
        <price curr="USD">12.00</price>
    </book>

    <book format="textbook">
        <name>Unity Game Development Essentials</name>
        <author>Will Goldstone</author>
        <price curr="CAD">52.00</price>
        <price curr="USD">45.00</price>
    </book>

    <book format="textbook">
        <name>UNIX Visual QuickPro</name>
        <author>Chris Herborth</author>
        <price curr="CAD">15.00</price>
        <price curr="USD">10.00</price>
    </book>
</catalog>

注意,我跟这里列出的作者和发行人没有任何联系,只有最后那个明显的除外。价格完全是瞎编的,至于实际的定价,您应该询问自己喜欢的书店。

 

XPath 假定

对于本文中的 XPath 代码,您要做以下假定:

  • 已经将 book.xml 文件(参见 清单 1)加载到您的 XPath 实现可以使用的格式。
  • 从一个表示文档根的对象开始搜索。就是以 <catalog> 元素作为子元素的那个对象。您将称之为 root,因为它是 XML 文档层次结构的根。

由于在太多不同的平台上有太多的 XPath 实现,所以下面我们将重点放在 XPath 语句本身上,并使用一个类似于 JavaScript 的伪代码来在上下文中展示这些语句;请查看您喜欢的开发平台的类库,了解有关加载 XML 文档和您可用的特定 XML 节点对象的信息。

 

jQuery 假定

本文中的 jQuery 代码做以下假定:

  • 使用的是最新(版本 1.4.0)jQuery 代码(参见 参考资料 中的链接)。
  • 已经通过 jQuery.get() 或 jQuery.post() 方法加载了 book.xml 文件,并且已经将最终的 XML 文档存储在一个名为 root 的变量中(与 XPath 例子相同)。

用于做这件事的一些样例代码在 清单 2 中。

清单 2. 利用 jQuery 加载 XML 样例
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
               "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
<title>Book Catalog</title>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js"></script>
<script type="text/javascript">// <![CDATA[
var root = null;

$(document).ready( function(){
    $.get( "http://localhost/~chrish/books.xml", 
        function( data ) {
            root = data;

            $("p#status").text( "Loaded." );
        } );
} );
// ]]></script>
</head>

<body>
<p id="status">
Loading book.xml...
</p>
</body>
</html>

在 $(document).ready() 函数中,使用 jQuery get() 方法从本地 Web 服务器加载 books.xml,将最终的文档对象存储在 root 变量中,并用status ID 设置段落的文本,以表明 XML 已完成加载。有关 jQuery 的更多信息,请查看本文末尾 参考资料 中的相关链接列表。

 

选择节点

XPath 和 jQuery 的基本目的都是从文档选择节点。一旦选择了一个节点(或一个节点集合),就可以找到您正在寻找的数据以及在需要时操纵文档。

XPath 设计用于确切返回您所寻找的节点;它一般非常特定。另一方面,jQuery 则使得操作大型节点集合非常容易,所以有时候您必须在开始处理节点之前小心地缩小匹配范围。

按名称选择节点

在搜索特定节点时,您通常知道它的名称,或者知道其父元素的名称。

要找到一个特定的元素,您会使用它的名称,如 清单 3 所示。

清单 3. 按名称选择节点
/* Find all <book> elements through XPath: */
var result = root.find( "//book" );

/* Find all <book> elements through jQuery: */
var result = $(root).find( "book" );

用于选择所有 <book> 元素的 XPath 语句(//book)使用两个斜杠 (//),来指定从当前节点(本例中是 root)开始、所有匹配的节点都会被找到。这是 jQuery 的默认行为,所以您不需要包含任何其他内容。在两种情况下,结果都是 清单 1 中的所有三个 <book> 元素。

通常可以通过指定元素路径来缩小搜索结果;结果将是自路径末尾的匹配节点(参见 清单 4)。

清单 4. 按路径选择节点—两者行为不同
/* Be more specific (XPath): */
var result = root.find( "/catalog//book" );

/* Be more specific (jQuery): */
var result = $(root).find( "catalog book" );

从根元素 (/) 开始,这个 XPath 语句将寻找第一个 <catalog> 元素,然后返回这第一个 <catalog> 元素下的所有 <book> 元素。jQuery 语句的行为稍有不同;它将返回所有 <catalog> 元素下的所有 <book> 元素(参见 清单 5)。对于例子 book.xml 文件,结果是相同的节点集,但是如果您想要得到 <book> 元素下的所有 <author> 元素,那会怎么样呢?跟 清单 3 中一样,应该以两个斜杠 (//) 开始 XPath 表达式。

清单 5. 按路径找出内含的节点—两个例子的行为一样
/* Get all authors from all books (XPath): */
var result = root.find( "//book//author" );

/* Get all authors from all books (jQuery): */
var result = $(root).find( "book author" );

要让 jQuery 跟 清单 4 中的 XPath 样例一样返回第一个 <catalog> 中的 <book> 元素,您必须指导它使用它找到的第一个 <catalog>(参见 清单 6)。

清单 6. 匹配第一个 catalog 中的 book—这些例子的行为一样
/* All books from the first catalog (XPath): */
var result = root.find( "/catalog//book" );

/* All books from the first catalog (jQuery): */
var result = $(root).find( "catalog:first book" );

找到元素的最后一次出现(比如项目列表中的最后一个列表项,或者选择列表中的最后一个选项)也是一个常见操作。要正确地将一些东西附加到列表末尾,需要知道此末尾的位置(参见 清单 7)。

清单 7. 找到 catalog 中的最后一个 book
/* The last book from the first catalog (XPath): */
var result = root.find( "/catalog/book[last()]" );

/* The last book from the first catalog (jQuery): */
var result = $(root).find( "catalog:first book:last" );

在两种情况下,您都得到第一个 <catalog> 元素中的最后一个 <book> 元素,这正是您在寻找的。在 XPath 例子中,last() 函数返回最后匹配元素的索引(用在方括号中)。

 

选择任意节点

有时,您不知道您在寻找的元素的名称,或者需要找到一个可能在几个不同元素中的元素。在 XPath 和 jQuery 中,都可以使用星号 (*) 来匹配任意元素(参见 清单 8)。

清单 8. any 元素
/* Find all authors in all elements inside of <catalog> (XPath): */
var result = root.find( "/catalog//*//author" );

/* Find all authors in all elements inside of <catalog> (jQuery): */
var result = $(root).find( "catalog:first * author" );

注意,我在 jQuery 样例中使用了 :first,以使它的行为完全跟 XPath 版本一样。

 

按属性选择节点

类似的元素通常具有独特的属性,比如 XHTML 元素中使用的 id 属性,是为了给 XHTML 元素一个惟一的引用 ID(参见 清单 9)。有时,您并不太关心特定的元素,而是关心一个属性为特定值的元素。

清单 9. 找到那些讨厌的教科书
/* Find all books that are textbooks (XPath): */
var result = root.find( "//book[@format='textbook']" );

/* Find all books that are textbooks (jQuery): */
var result = $(root).find( "book[format='textbook']" );

两个例子都将返回所有具有 format 属性且属性值设置为 textbook 的 <book> 元素(清单 1 中的 book.xml 文件中有两个这样的元素)。XPath 的语法使用一个 @ 符号来匹配属性(jQuery 只是将属性括在方括号中),您需要包含两个斜杠 (//) 来匹配所有 <book> 元素,但是两个查询非常类似,都很直观。

针对 XHTML 中两个最常见的匹配属性(id 和 class),jQuery 包含了两个快捷方式。在 XPath 中,您必须显式地写出它们(参见 清单 10)。

清单 10. 基于 id 和 class 属性匹配 XHTML
/* Find the "status" <p>, then the highlighted elements (XPath) */
var result1 = xhtml_root.find( "//p[@id='status']" );
var result2 = xhtml_root.find( "//*[@class='highlight']" );

/* Find the "status" <p>, then the highlighted elements (jQuery) */
var result1 = $( "p#status" );
var result2 = $( ".highlight" );

假设您的 XHTML 文档是有效的(确实是的,对吧?),ID 匹配查询将只返回一个元素,因为在有效的 XML 文档中,ID 必须是惟一的。

如果您是层叠样式表(Cascading Style Sheets,CSS)的粉丝,可能注意到了,jQuery 选择器几乎跟 CSS 选择器完全相同。这很方便,因为您只需要记住一个针对通过 jQuery 找到想要的元素和利用 CSS 为元素定义样式的标准。

多个选择器

XPath 和 jQuery 都允许您组合多个选择器来检索每个匹配任意查询的节点(就是说,将得到结果的并集)。在 XPath 中,用竖线 (|) 字符组合语句,而在 jQuery 中则使用逗号 (,)(参见 清单 11)。

清单 11. 找到多个选择器的结果
/* Find all book names and all authors (XPath) */
var result = root.find("//name|//author" );

/* Find all book names and all authors (jQuery) */
var result = $(root).find( "name,author" );

在两种情况下,结果都是文档任何地方所有 <name> 和 <author> 元素的列表。在 图 1 中,使用 AquaPath 查看 XPath 结果(AquaPath 是一个用于 Mac OS X Tiger 的工具,有关它的更多信息,请参见 参考资料)。

图 1. XPath 结果,book.xml 文件中所有 book 的 name 和 author 标记都已突出显示
XPath 结果的屏幕截图,book.xml 文件中所有 book 的 name 和 author 标记都已突出显示
 

遍历节点

除了选择节点之外,通常还需要遍历文档结构,以便找到相关的数据或者执行复杂的操作。XPath 和 jQuery 都可以帮助您遍历文档。

根据前面学习的内容,您可以使用这些遍历方法来帮助找到祖先(即包含当前元素的元素)或子孙(即当前元素包含的元素)。

例如,清单 12 用于找到包含您找到的最后一个 <book> 的 <catalog>。

清单 12. 哪个 catalog 列出最后一个 book?
/* Find the catalog for the last book you know about (XPath) */
var result = root.find( "//book[last()]/ancestor::catalog" );

/* Find the catalog for the last book you know about (jQuery) */
var result = $(root).find( "book:last" ).closest( "catalog" );

图 2 显示了结果。

图 2. 最后一个 book 的 catalog 祖先
突出显示的 catalog 标记的屏幕截图,该标记是 book.xml 中最后一个 book 的 catalog 祖先

有一件事要注意,jQuery closest() 方法的行为很像 XPath 的 ancestor-or-self;如果匹配的话,它将包含当前节点。在本例中它不包含当前节点,但是如果您可以嵌套名称相同的元素或者是在匹配属性,那么应该牢记这件事。

如果需要朝另一个方向走,找到嵌入在您已经找到的元素中的元素,也是可以做到的(参见 清单 13)。

清单 13. 找到列出在 catalog 中的 price
/* Find the prices of everything in the catalog. (XPath) */
var result = root.find( "//catalog/descendant::price" );

/* Find the prices of everything in the catalog. (jQuery) */
var result = $(root).find( "catalog price" );

对于那些特殊情况,即选择的节点可能匹配您正在寻找的元素,那么跟 XPath 中的祖先一样,子孙也具有 descendant-or-self(参见 图 3)。

图 3. 所有 price,已选中
突出显示的 price 标记的屏幕截图,这是 book.xml 中列出的 book 中的 price
 

模拟高级 XPath 特性

XPath 指定了很多在 jQuery 中不必要的有用特性;毕竟,jQuery 运行在浏览器中,可以充分利用 JavaScript 的优势,而 XPath 通常用于比较受限的环境中,比如 XSLT 处理。

当然,只要您想用,这并不能阻止您用 JavaScript 实现这些特性。

很容易数清查询结果的个数(参见 清单 14)。

清单 14. 多少节点匹配选择器?
/* How many price entries do you have? (XPath) */
var result = root.find( "count(//price)" );

/* How many price entries do you have? (jQuery) */
var result = $(root).find( "price" ).length;

有时只需要知道节点是否包含某个字符串(参见 清单 15)。

清单 15. 第三个 <author> 中包含 Chris 吗?
/* Does the third <author> have "Chris" in its contents? (XPath) */
var result = root.find( "contains(//book[3]/author,'Chris')" );

/* Does the third <author> have "Chris" in its contents? (jQuery) */
var result = $(root).find( "book:eq(2) author:contains('Chris')" ).length > 0

清单 15 中有一个非常重要的区别需要注意,XPath 的索引从 1 开始,不是从 0 开始。在 jQuery 中,必须使用 :eq(2) 来得到第三个结果。

XPath 也有一个 sum() 函数,它以匹配节点的内容作为参数,将这些参数转换成数值,并返回这些值的和。在使用 jQuery 时,必须编写一个简短的函数来模拟该函数(参见 清单 16)。

清单 16. 计算一些节点内容的和
/* Sum the Canadian prices (XPath) */
var result = root.find( "sum(//price[@curr='CAD'])" );

/* Sum the Canadian prices (jQuery) */
function sum( root, selector ) {
    var x = 0;
    $(root).find( selector ).map( function() {
        if( this.text ) {
            // Internet Explorer-only
            return x += ( this.text * 1 );
        }

        // Firefox and W3C-compliant browsers
        return x += ( this.textContent * 1 );
    } );
    return x;
}

var result = sum( root, "price[curr='CAD']" );

jQuery 中的 map() 方法为每个结果节点运行指定的函数。注意,要得到结果节点的内容,也必须稍微费点事。确保在所有您喜欢的浏览器上测试这类 JavaScript。

您现在应该比较能理解何时以及如何将 XPath 1.0 和 jQuery 1.4 用于类似的任务了。

 

结束语

对于从格式良好的 XML 文档(包括 XHTML 页面)选择节点,XPath 和 jQuery 具有强大的查询语义。尽管它们的语法不同,但是无论使用哪一个来基于元素名或属性值从文档选择重要的或感兴趣的节点,都相当容易。

对于匹配与当前匹配的元素相关的元素节点,XPath 和 jQuery 都支持直观的遍历语义。此外,由于 jQuery 运行在完全的 JavaScript 解释器中,所以您可以用少量的代码模拟 XPath 的一些高级特性。

 

https://www.ibm.com/developerworks/cn/xml/x-xpathjquery/

分享到:
评论

相关推荐

    xpath-helper.zip

    xpath-helper

    javascript-xpath-latest.js

    1. 更换默认的xpath库 除了ie,其他主要浏览器都是内置对xpath的支持的,但ie不行,所以selenium 使用了javascript库,默认使用的是ajaxslt,这个会比较慢,可以换成 javascript-xpath, 虽然比firefox还是慢...

    JsoupXpath-0.3.2.jar 完整版

    JsoupXpath 是一款纯Java开发的使用xpath解析提取html数据的解析器,针对html解析完整... 为了在java里也享受xpath的强大与方便但又苦于找不到一款足够好用的xpath解析器,故开发了JsoupXpath。(适用于XML快捷查询)

    JsoupXpath-0.3.2.jar.rar

    JsoupXpath-0.3.2.jar.rar

    xpath-helper

    xpath-helper可以加入到chrome中作为插件来用,shift+ctrl+x是快捷键。爬虫的时候可以快速定位和反定位!

    XPath注入漏洞利用工具XPath-XCat.zip

    XCat是一个命令行程序,用于辅助XPath注入漏洞的利用。XCat使用Python编写并开放源代码。XCat正常使用需要python的SimpleXMLWriter模块。 标签:XPath

    xpath--java框架技术

    xpath--java框架技术

    XPath-Helper

    xpath-helper,可以在谷歌中添加 该插件,直接获取xpath,非常便捷

    XPath-Helper_v2.0.2.crx.zip

    浏览器插件使用 1. 解压文件 2. 右上角三个点&gt;&gt;&gt;更多工具&gt;&gt;&gt;扩展工具&gt;&gt;&gt;点开开发者模式&gt;&gt;&gt;加载已解压的扩展程序

    XPath-Solve.rar

    XPath-Solve.rar XPath-Solve.rar XPath-Solve.rar

    JsoupXpath-2.4.3.7z

    JsoupXpath-2.4.3-javadoc.jar JsoupXpath-2.4.3-sources.jar JsoupXpath-2.4.3.jar

    xpath-helper插件.zip

    谷歌xpath-helper插件

    xpath-helper插件

    chrome浏览器的xpath插件,xpath是用来解析网页内容的,而xpath-helper可以很好的编写xpath规则

    xpath-helper_v1_v2.zip

    里面包含v1 和v2两个版本;开始我装了v1,但是没能打开;装了v2可以使用。 我把两个一起上传了,不谢

    perl-XML-XPath-1.13-22.el7.noarch.rpm

    离线安装包,亲测可用

    JsoupXpath-0.3.2.jar

    java的包使用jsou相关会用到

    jsoup-1.11.2.jar JsoupXpath-0.3.2

    java的两个包 JsoupXpath-0.3.2 jsoup-1.11.2 解析xml

    xpath-helper for MAC

    Xpath helper 2.0.2,适用于MAC版, 提供的了压缩包,下载后,解压缩-打开chrome-&gt;更多工具-&gt;扩展程序-&gt;加载已经解压的扩展程序-&gt;找到解压的文件夹选中,此时会发现地址栏后面多了一个“X”的图标,此时F12,点击...

    perl-XML-XPath-1.42-3.el8.noarch(1).rpm

    官方离线安装包,亲测可用

Global site tag (gtag.js) - Google Analytics