XPath是设想用来在DOM文档中查找节点的一种手腕,因而对XML的处置惩罚也很主要。许多浏览器完成了这个范例,IE有本身的完成体式格局。
DOM3级XPath
下面的代码是用来检测浏览器是不是支撑DOM3级的XPath:
var supportsXPath=document.implementation.hasFeature("XPath","3.0");
在DOM3级的XPath范例定义的范例中,最主要的两个范例是
XPathEvaluator
XPathResult
XPathEvaluator
用在特定的高低文中对XPath表达式的求值。这个范例由三个要领:
createExpression(expression,nsresolver)
:将XPath表达式及响应的定名空间信息转化成一个XPathExpression,这是查询的编译版。在屡次运用同一个查询时很有效。createNSResolver(node)
:依据node的定名空间信息建立一个新的XPathNSResolver对象。在基于运用定名空间的XML文档求值时,须要运用XPathNSResolver对象。evaluate(expression.context,nsresolver,type,result)
:在给定的高低文中基于特定的定名空间信息来对XPath求值,剩下的参数指定怎样返回效果。
evaluate要领最经常使用。这个要领吸收5个参数:
XPath表达式
高低文节点
定名空间求解器
返回效果的范例和保留效果的XPathResult对象(通常是null,由于效果会以函数值的情势返回)。
第三个参数只在XML代码中运用了XML定名空间时有必要指定,假如没运用,设置为null。
第四个参数的的取值局限是以下的常量之一:
XPathResult.ANY_TYPE
:返回与XPath表达式婚配的数据范例XPathResult.NUMBER_TYPE
:数字XPathResult.STRING_TYPE
:字符串XPathResult.BOOLEAN_TYPE
:布尔值XPathResult.UNORDERED_NODE_ITERATOR_TYPE
:无序的婚配节点鸠合XPathResult.ORDERED_NODE_ITERATOR_TYPE
:有序的节点婚配鸠合XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE
:无序的婚配节点快照鸠合XPathResult.ORDERD_NODE_SNAPSHOT_TYPE
:有序的婚配节点快照鸠合XPathResult.ANY_UNORDERED_NODE_TYPE
:返回婚配的节点鸠合,递次会与原文不一定一致。XPathResult.FIRST_ORDERED_NODE_TYPE
:返回一个节点的鸠合
指定的效果范例决议了怎样获得效果的值。
var result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.ORDERED_NODE_ITERATOR_TYPE, null);
if (result !== null) {
var node = result.iterateNext();
while (node) {
alert(node.tagName);
node = result.iterateNext();
}
}
上述代码中返回的XPathResult点迭代器须要运用iterateNext()
要领从节点中获得婚配的节点。
再举个例子如:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>","text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.ORDERED_NODE_ITETATOR_TYPE, null);
if (result !== null) {
var node = result.iterateNext();
while (node) {
console.log(node.innerHTML);
node = result.iterateNext();
}
}
假如指定的是快照效果范例,就必须运用
snapshotItem()
要领和snapshotLength
属性。
如:
var result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (result !== null) {
for (var i = 0, len = result.snapshotLength; i < len; i++) {
alert(result.snapshotItem(i).tagName);
}
}
又如:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
if (result !== null) {
for (var i = 0, len = result.snapshotLength; i < len; i++) {
console.log(result.snapshotItem(i).innerHTML);
};
}
单节点效果
XPathResult.FIRST_ORDERED_NODE_TYPE
会返回一个婚配的节点,能够经由过程效果的singleNodeValue
属性来访问该节点。
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
console.log(result.singleNodeValue.innerHTML); //Oliver
能够经由过程singleNodeValue
属性来访问该节点。
简朴范例效果
简朴范例的效果离别会经由过程
booleanValue
numberValue
stringValue
来访问。
XPathResult.BOOLEAN_TYPE
:
关于布尔值范例,假如至少有一个节点与XPath表达式婚配,则求值效果返回true,不然返回false:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.BOOLEAN_TYPE, null);
console.log(result.booleanValue); //True
假如有节点婚配”employee/name”,则返回true;
XPathResult.NUMBER_TYPE
和count()
要领:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("count(/root/name)", xmldom.documentElement, null, XPathResult.NUMBER_TYPE, null);
console.log(result.numberValue); //2
以上输出与XPath语法婚配的节点数目(2)
XPathResult.STRING_TYPE
:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.STRING_TYPE, null);
console.log(result.stringValue); //Oliver
默许范例效果
XPathResult.ANY_TYPE
常量
能够自动肯定返回效果的范例。
resultType
属性
能够检测效果的范例。
如:
var xmldom = null;
var parser = new DOMParser();
xmldom = parser.parseFromString("<root><name>Oliver</name><name>Troy</name></root>", "text/xml");
var result = xmldom.evaluate("/root/name", xmldom.documentElement, null, XPathResult.ANY_TYPE, null);
if (result !== null) {
switch (result.resultType) {
case XPathResult.STRING_TYPE:
console.log(result.stringValue);
break;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
var node = result.iterateNext();
while (node) {
console.log(node.innerHTML);
node = result.iterateNext();
}
break;
}
}
对运用定名空间的XML求值的要领:
createNSResolver()
要领
和建立一个函数,两种要领
经由过程
createNSResolver(node)
要领来建立XPathNSResolver
对象, 然后再运用evaluate() 要领来猎取效果
如:
var nsresolver = xmldom.createNSResolver(xmldom.documentElement);
var result = xmldom.evaluate("wrox:book/wrox:author", xmldom.documentElement, nsresolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
alert(result.snapshotLength);
定义一个函数, 让它吸收一个定名空间前缀, 返回关联的URI
如:
var neresolver = function(prefix) {
switch (prefix) {
case "wrox":
return "http://www.wrox.com/";
//其他前缀
}
}
var result = xmldom.evaluate("count(wrox:book/wrox/author)", xmldom.documentElement, nsresolver, XPathResult.NUMBER_TYPE, null);
alert(result.numberValue);
跨浏览器运用XPath
第一个跨浏览器的要领是selectSingleNode()
, 吸收三个参数: 高低文节点, XPath表达式, 可选的定名空间
function selectSingleNode(context, expression, namespace) {
var doc = (context.nodeType != 9 ? context.ownerDocument : context);
if (typeof doc.evaluate != "umdefined") {
var nsresolver = null;
if (namespace instanceof Object) {
nsresolver = function(prefix) {
return namespace[prefix];
};
}
var result = doc.evaluate(expression, context, nsresolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null);
return (result !== null ? result.singleNodeValue : null);
} else if (typeof context.selectSingleNode != "undefined") {
if (namespace instanceof Object) {
var ns = "";
for (var prefix in namespace) {
if (namespaces.hasOwnProperty(prefix)) {
ns += "xmlns:" + prefix + "='" + namespaces[prefix] + "' ";
}
}
doc.setProperty("SelectionNamespaces": ns);
}
return context.selectSingleNode(expression);
} else {
throw new Error("no XPath engine found");
}
}
下面是这个函数的运用示例:
var result = selectSingleNode(xmldom.documentElement, "wrox:book/wrox:author", {
wrox: "http://www.wrox.com/"
});
alert(serializeXml(result));
下面的函数是跨浏览器封装的selectNodes()
函数, 这个函数吸收与上一个函数有雷同的三个参数。
function selectNodes(context, expression, namespace) {
var doc = (context.nodeType != 9 ? context.ownerDocument : context);
if (typeof doc.evaluate != "umdefined") {
var nsresolver = null;
if (namespace instanceof Object) {
nsresolver = function(prefix) {
return namespace[prefix];
};
}
var result = doc.evaluate(expression, context, nsresolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var nodes = new Array();
if (result !== null) {
for (var i = 0, len = result.snapshotLength; i < len; i++) {
nodes.push(result.snapshotItem(i));
}
}
return nodes;
} else if (typeof context.selectSingleNode != "undefined") {
if (namespace instanceof Object) {
var ns = "";
for (var prefix in namespace) {
if (namespace.hasOwnProperty(prefix)) {
ns += "xmlns:" + prefix + "='" + namespaces[prefix] + "' ";
}
}
doc.setProperty("SelectionNamespaces": ns);
}
var result = context.selectNodes(expression);
var nodes = new Array();
for (var i = 0, len = result.length; i < len; i++) {
nodes.push(result[i]);
}
return nodes;
} else {
throw new Error("no XPath engine found");
}
}
下面是selectNodes() 要领的运用示例:
var result = selectNodes(xmldom.documentElement, "wrox:book/wrox:author", {
wrox: "http://www.wrox.com/"
});
alert(result.length);