JavaScript JavaScript与XML——“XPath”的注重要点

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个参数:

  1. XPath表达式

  2. 高低文节点

  3. 定名空间求解器

  4. 返回效果的范例和保留效果的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_TYPEcount()要领:

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()要领

和建立一个函数,两种要领

  1. 经由过程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);
  1. 定义一个函数, 让它吸收一个定名空间前缀, 返回关联的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);
    原文作者:JS菌
    原文地址: https://segmentfault.com/a/1190000004476200
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞