`
m635674608
  • 浏览: 5028120 次
  • 性别: 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.crx"很可能是一个Chrome浏览器的扩展程序,旨在提供实时的XPath查询支持。 XPath(XML Path Language)是一种在XML文档中查找信息的语言,它允许我们通过路径表达式来选取节点,如元素、...

    JsoupXpath-0.3.2.jar.rar

    在JsoupXpath-0.3.2.jar中,开发者可以利用XPath查询语言来定位和操作HTML文档中的特定部分,这极大地增强了Jsoup的功能,使其在处理复杂网页结构时更具灵活性。 这个压缩包包含两个文件:JsoupXpath-0.3.2.jar是...

    javascript-xpath-latest.js

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

    XPath-Helper

    XPath-Helper是一款针对XPath查询的高效工具,特别为谷歌浏览器设计,极大地简化了网页元素的选择和XPath表达式的构建过程。 在网页开发、自动化测试、数据抓取等领域,XPath-Helper扮演着至关重要的角色。通过安装...

    XPath-Helper_v2.0.2.crx.zip

    XPath Helper是一款非常实用的浏览器插件,主要用于帮助开发者和数据分析师在网页中便捷地查找、测试和使用XPath表达式。XPath是一种在XML文档中查找信息的语言,它能够定位到XML或HTML文档中的节点,包括元素、属性...

    JsoupXpath-0.3.2.jar 完整版

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

    xpath-helper插件.zip

    谷歌xpath-helper插件

    xpath-helper

    用户可以通过安装CRX文件(即`xpath-helper.crx`)来添加这个插件。XPath(XML Path Language)是一种在XML文档中查找信息的语言,它能够有效地选取XML或HTML文档中的节点,如元素、属性、文本等。 XPath Helper的...

    xpath-helper_v1_v2.zip

    1. 在网页上选择任何元素,插件会自动生成对应的XPath表达式,这对于理解和学习XPath非常有帮助。 2. 输入自定义的XPath表达式,插件会高亮显示所有匹配的元素,帮助定位问题或验证表达式的正确性。 3. 利用插件提供...

    xpath-as3-1.0.1

    API参考文档通常会列出库中所有的类、方法、属性和函数,以及它们的使用方式和参数说明,这对于使用XPath-as3库编写代码非常有用。教程和示例代码则可以帮助开发者快速上手,理解如何在实际项目中应用XPath查询。 ...

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

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

    xpath-helper工具

    在提供的压缩包文件中,`xpath-helper.crx`是一个Chrome浏览器扩展程序的文件。这类文件通常用于安装到浏览器,为用户提供特定的功能或增强浏览器体验。要安装此扩展,用户需要将.crx文件拖放到Chrome浏览器的扩展...

    JsoupXpath-2.4.3.7z

    1. **JsoupXpath-2.4.3-javadoc.jar**: 这个文件包含了JsoupXpath库的API文档。JavaDoc是一种标准工具,用于从源代码中生成易于理解的文档,它详细列出了库中的类、接口、方法及其参数、返回类型和注释。开发者...

    xpath-help插件

    总的来说,XPath-help插件通过提供直观的用户界面和强大的XPath支持,使得在Chrome浏览器中探索和操作网页内容变得轻而易举。只需简单的几步设置,你就可以充分利用XPath的强大功能,解决网页数据提取和分析中的各种...

    Chrome插件Xpath-helper 下载了几个都没用,这个终于可以用了

    标题中的问题反映了一些用户在尝试下载和使用Xpath-helper插件时遇到的困扰,可能的原因包括但不限于以下几点: 1. 插件兼容性问题:不同版本的Chrome浏览器可能对某些插件的支持度不同,导致部分插件无法正常工作...

    xpath-helper 插件及使用方法

    3. **生成XPath**:浏览目标网页,右键点击需要定位的元素,选择“检查”或者“Inspect”,然后在开发者工具中复制XPath路径。 4. **测试XPath**:在XPath Helper的输入框中粘贴XPath表达式,点击运行,查看匹配...

    谷歌浏览器xpath-helper

    【谷歌浏览器xpath-helper】是一款强大的开发者工具,专为在谷歌浏览器(Chrome)中方便地使用XPath查询和调试网页元素而设计。XPath是一种在XML文档中查找信息的语言,它被广泛应用于网页抓取、自动化测试以及网页...

    xpath--java框架技术

    在Java框架中,XPath通常与其他技术结合使用,如DOM解析器(用于解析XML文档)和JAXB(用于XML与Java对象之间的绑定)。例如,当我们处理一个XML配置文件时,可能会先用XPath定位到配置项,然后用JAXB将其转换为Java...

    XPath-Solve.rar

    XPath-Solve.rar 是一个压缩包,包含了多个与XPath和XML处理相关的资源,特别是针对Java环境下的应用。XPath是一种在XML文档中查找信息的语言,而Java是广泛使用的编程语言,经常用于处理XML数据。这个压缩包可能是...

Global site tag (gtag.js) - Google Analytics