非常教程

Xslt & Xpath参考手册

其他杂项 | Miscellaneous

Snippets

本文提供了一些XPath代码片段 - 简单的例子,介绍如何基于DOM Level 3 XPath规范中的标准接口提供一些简单的实用程序函数,以便将XPath功能展示给JavaScript代码。片段是您可以在自己的代码中在现实世界中使用的函数。

特定于节点的评估程序功能

以下自定义实用程序功能可用于评估给定XML节点上的XPath表达式。第一个参数是一个DOM节点或Document对象,而第二个参数是一个定义XPath表达式的字符串。

示例:定义自定义节点特定的evaluateXPath()效用函数
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function evaluateXPath(aNode, aExpr) {
  var xpe = new XPathEvaluator();
  var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
    aNode.documentElement : aNode.ownerDocument.documentElement);
  var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
  var found = [];
  var res;
  while (res = result.iterateNext())
    found.push(res);
  return found;
}

此功能使用new XPathEvaluator()构造函数,该函数在Firefox,Chrome,Opera和Safari中受支持,但不在Edge或Internet Explorer中受支持。可能由Edge或Internet Explorer用户访问的Web文档中的脚本应将呼叫替换new XPathEvaluator()为以下片段:

  // XPathEvaluator is implemented on objects that implement Document
  var xpe = aNode.ownerDocument || aNode;

在这种情况下,XPathNSResolver的创建可以简化为:

  var nsResolver = xpe.createNSResolver(xpe.documentElement);

但是请注意,createNSResolver只有在确定XPath表达式中的名称空间前缀与要查询的文档中的名称空间前缀匹配时(以及没有使用默认名称空间(尽管请参阅document.createNSResolver以获得解决方法)),才应使用它。否则,你必须提供你自己的XPathNSResolver实现。

如果您使用XMLHttpRequest将本地或远程XML文件读入DOM树(如解析和序列化XML中所述),则evaluateXPath()应该使用第一个参数req.responseXML

示例用法

假设我们有以下XML文档(另请参阅如何创建DOM树以及解析和序列化XML):

示例:用于自定义evaluateXPath()实用程序功能的XML文档
<?xml version="1.0"?>
<people>
  <person first-name="eric" middle-initial="H" last-name="jung">
    <address street="321 south st" city="denver" state="co" country="usa"/>
    <address street="123 main st" city="arlington" state="ma" country="usa"/>
  </person>

  <person first-name="jed" last-name="brown">
    <address street="321 north st" city="atlanta" state="ga" country="usa"/>
    <address street="123 west st" city="seattle" state="wa" country="usa"/>
    <address street="321 south avenue" city="denver" state="co" country="usa"/>
  </person>
</people>

您现在可以使用XPath表达式“查询”文档。尽管漫步DOM树可以获得类似的结果,但使用XPath表达式更快更强大。如果你可以依赖id属性,document.getElementById()仍然强大,但它不如XPath强大。这里有些例子。

示例:使用自定义evaluateXPath()实用程序功能的JavaScript代码
// display the last names of all people in the doc
var results = evaluateXPath(people, "//person/@last-name");
for (var i in results)
  alert("Person #" + i + " has the last name " + results[i].value);

// get the 2nd person node
results = evaluateXPath(people, "/people/person[2]");

// get all the person nodes that have addresses in denver
results = evaluateXPath(people, "//person[address/@city='denver']");

// get all the addresses that have "south" in the street name
results = evaluateXPath(people,  "//address[contains(@street, 'south')]");
alert(results.length);

docEvaluateArray

下面是一个简单的实用函数,用于将(有序的)XPath结果获取到数组中,而不管是否存在对名称空间解析器的特殊需求等。它避免了document.evaluate()不需要的情况下更复杂的语法以及需要使用特殊的迭代器XPathResult(而不是返回一个数组)。

示例:定义一个简单的docEvaluateArray​()效用函数
// Example usage:
// var els = docEvaluateArray('//a');
// alert(els[0].nodeName); // gives 'A' in HTML document with at least one link

function docEvaluateArray (expr, doc, context, resolver) {
    var i, result, a = [];
    doc = doc || (context ? context.ownerDocument : document);
    resolver = resolver || null;
    context = context || doc;
	
    result = doc.evaluate(expr, context, resolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for(i = 0; i < result.snapshotLength; i++) {
        a[i] = result.snapshotItem(i);
    }
    return a;
}

getXPathForElement

以下函数允许传递一个元素和一个XML文档来查找一个返回该元素的唯一字符串XPath表达式。

示例:定义一个getXPathForElement​​()效用函数
function getXPathForElement(el, xml) {
	var xpath = '';
	var pos, tempitem2;
	
	while(el !== xml.documentElement) {		
		pos = 0;
		tempitem2 = el;
		while(tempitem2) {
			if (tempitem2.nodeType === 1 && tempitem2.nodeName === el.nodeName) { // If it is ELEMENT_NODE of the same name
				pos += 1;
			}
			tempitem2 = tempitem2.previousSibling;
		}
		
		xpath = "*[name()='"+el.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']["+pos+']'+'/'+xpath;

		el = el.parentNode;
	}
	xpath = '/*'+"[name()='"+xml.documentElement.nodeName+"' and namespace-uri()='"+(el.namespaceURI===null?'':el.namespaceURI)+"']"+'/'+xpath;
	xpath = xpath.replace(/\/$/, '');
	return xpath;
}

资源

  • XPath
  • Forum discussion on this topic

其他杂项 | Miscellaneous相关

Xslt & Xpath

XSLT 是扩展样式表转换语言 的外语缩写,这是一种对 XML(标准通用标记语言的子集)文档进行转化的语言,XSLT 中的 T 代表英语中的“转换”(Transformation)。它是 XSL(eXtensible Stylesheet Language)规范的一部分

Xslt & Xpath目录

1.其他杂项 | Miscellaneous
2.XPath 轴 | XPath Axes
3.XSLT元素 | XSLT Elements
4.XPath 函数 | XPath Functions
5.XPath 教程
6.XPath 实例
7.XPath 运算符
8.XPath 轴(Axes)
9.XPath 语法
10.XPath 节点
11.XPath 简介
12.XPath、XQuery 以及 XSLT 函数
13.XPath 总结