浏览器中的XPath支持

来源:互联网 发布:网页cc源码 编辑:程序博客网 时间:2024/05/14 23:42
因为XML用于处理多种数据,所以必须有一种可以在XML代码中定位数据的方式。这个问题的答案就是XPath,它是专门用于定位匹配模式的一个或多个节点的小语言。尽管关于XPath深入的讨论已经超出本书的范围,不过还是要进行一些简单的介绍。
15.2.1  XPath简介
每个XPath表达式都有两部分:一个上下文节点和一个节点模式。上下文节点提供了节点模式起始的位置。节点模式是由一个或多个节点选择器组成的字符串。
例如,考虑以下XML文档:
同时考虑这个XPath表达式:
如果上下文节点是<employees/>,则前面的XPath表达式就匹配了<name>Nicholas C. Zakas</name><name>Jim Smith</name>。在这个表达式中,employeename都表示XML元素的标签名,按照它们在上下文节点中出现的顺序;斜杠表示从父节点到子节点的关系。这个XPath表达式表示:从<employees/>起,匹配位于<employee/>元素下的子节点<name/>元素。
要选择地<employee/>元素的第一个<name/>元素,表达式要变成:
在XPath中,方框记号用于为某个节点提供更加确切的信息。这个例子使用了XPath的position()函数,它用于返回元素在父节点下的位置。第一个子节点的位置为1,所以将position()1进行比较则只能匹配第一个<employee/>元素。然后,斜杠和name匹配在第一个<employee/>元素下的<name/>元素。
除位置和名称外,还可以使用不同的方法来匹配元素。假设要选择所有title特性等于"Salesperson"的<employee/>元素,则XPath表达式变成:
在表达式中,@attribute的缩写。
XPath是一种十分强大的表达式可以令在DOM文档中查找指定节点变得很容易。因此,IE和Mozilla都在DOM实现中引入了XPath支持。
如果想了解更多关于XPath的信息请参阅XPath 2.0: Programmer’s ReferenceWiley出版社ISBN 0-7645-6910-4
15.2.2  IE中的XPath支持
看来,微软对直接在XML DOM对象中建立XPath支持感觉很惬意。每个节点都有两个可用于获取匹配XPath模式的节点的方法:selectNodes(),用于返回匹配某个模式的节点的集合; selectSingleNode(),用于返回匹配给定模式的第一个节点。
使用前面一节中的数据,可用下面的代码选择所有<employee/>元素下的<name/>元素:
因为selectNodes()是作为oXmlDom.documentElement的方法调用的,所以文档元素被看作XPath表达式的上下文节点。方法返回包含所有匹配给定模式的节点的NodeList,也就是说,可以这样迭代所有的元素:
如果没有匹配给定模式的节点,还是会返回NodeList。如果为空,则它的length属性值等于0。
selectNodes()的返回结果活的列表,所以如果用另外一个匹配XPath表达式的节点更新该文档,则这个元素会自动被添加到NodeList的合适位置。
如果只需要匹配模式的第一个元素,则可以使用selectSingleNode()
如果发现了节点,则selectSingleNode()方法返回一个Element,否则它返回null
15.2.3  Mozilla中的XPath支持
Mozilla是根据DOM标准来实现对XPath的支持的。DOM Level 3附加标准DOM Level 3 XPath定义了用于在DOM中计算XPath表达式的接口。遗憾的是,这个标准要比微软直观的方式复杂得多。
虽然有好多与XPath相关的对象,最重要的两个是:XPathEvaluatorXPathResultXpathEvaluator利用方法evaluate()计算XPath表达式。
evaluate()方法有五个参数:XPath表达式、上下文节点、命名空间解释程序和返回的结果的类型,同时,在XPathResult中存放结果(通常为null)。
命名空间解释程序,只有在XML代码用到了XML命名空间时才是必要的,所以通常留空,置为null。返回结果的类型,可以是以下十个常量值之一:
XPathResult.ANY_TYPE——返回符合XPath表达式类型的数据;
XPathResult.ANY_UNORDERED_NODE_TYPE——返回匹配节点的节点集合,但顺序可能与文档中的节点的顺序不匹配;
XPathResult.BOOLEAN_TYPE——返回布尔值;
XPathResult.FIRST_ORDERED_NODE_TYPE——返回只包含一个节点的节点集合,且这个节点是在文档中第一个匹配的节点;
XPathResult.NUMBER_TYPE——返回数字值;
XPathResult.ORDERED_NODE_ITERATOR_TYPE——返回匹配节点的节点集合,顺序为节点在文档中出现的顺序。这是最常用到的结果类型;
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE——返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点与它们出现在文档中的顺序一样;
XPathResult.STRING_TYPE——返回字符串值;
XPathResult.UNORDERED_NODE_ITERATOR_TYPE——返回匹配节点的节点集合,不过顺序可能不会按照节点在文档中出现的顺序排列;
XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE——返回节点集合快照,在文档外捕获节点,这样将来对文档的任何修改都不会影响这个节点列表。节点集合中的节点和文档中原来的顺序不一定一样。
指定的结果类型决定了如何获取结果的值。下面是个典型的例子:
这个例子使用了XPathResult. ORDERED_NODE_ITERATOR_TYPE结果,它是最常用到的结果类型。如果没有节点匹配XPath表达式,evaluate()返回null;否则,它返回一个XPathResult对象。如果结果是个节点迭代子,不管它是有序的还是无序的,都可以不断用iterateNext()方法获取在结果中的每一个匹配的结果。如果没有更多匹配的节点,iterateNext()返回null。可以用节点迭代子为Mozilla创建一个selectNodes()方法:
Element类添加selectNodes()方法以模仿IE中的行为。调用evaluate()时,把用this关键字作为上下文节点(这也是IE的工作方式)。然后,在结果数组(aNodes)中放入匹配的节点。新方法用法如下:
如果指定了快照结果类型(不管是有序的还是无序的),都可使用snapshotItem()以及snapshotLength()方法,如下例所示:
在这个例子中,snapshotLength返回节点的数量,snapshotItem()返回快照中给定位置上的节点(类似于NodeListlengthitem()).
XPathResult.FIRST_ORDERED_NODE_TYPE结果返回第一个匹配的节点,可通过singeNode Value特性来访问:
你肯定已猜到,这段代码可用来模仿IE的selectSingleNode()方法:
这个方法的用法与在IE中的一样:
XpathResult类型最后部分就是布尔类型、数字类型和字符串类型。其中,每个结果类型中都用相应的booleanValuenumberValuestringValue来返回单个值。对于布尔类型,一般返回true,只需有一个节点匹配了XPath表达式,否则返回false
在此例中,如果任何节点匹配了"employee/name",booleanValue特性都等于true
对于数字类型,XPath表达式必须使用返回数字的XPath函数,诸如count(),它可用于计算匹配给定模式的节点的个数:
这段代码输出了匹配模式"employee/name"(2个)。如果不使用这种特殊的XPath函数便使用这个方法,numberValue则等于NaN
对于字符串类型,evaluate()方法查找第一个匹配XPath表达式的节点,然后返回第一个子节点的值(假设第一个子节点是文本节点)。否则,结果是空字符串。例:
前面的代码将输出"Nicholas C. Zakas",因为这是在<employee/>元素下<name/>元素中的第一个文本节点。
如果觉得这比较危险,可以使用XPathResult.ANY_TYPE。通过指定结果类型,使evaluate()根据XPath表达式返回最合适的结果类型。一般来说,这个结果类型是个布尔值,字符串值或者是无序的节点迭代子。要判断返回的结果类型,可使用resultType特性:
你已经看出来了,Mozilla中的XPath计算远比IE的复杂,当然也更加强大。通过使用自定义的selectNodes()selectSingleNode()方法,可以在两种浏览器上使用同样的代码进行XPath计算。