资讯专栏INFORMATION COLUMN

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

duan199226 / 460人阅读

摘要:对于布尔值类型,如果至少有一个节点与表达式匹配,则求值结果返回,否则返回如果有节点匹配,则返回和方法以上输出与语法匹配的节点数量默认类型结果常量可以自动确定返回结果的类型。

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("OliverTroy","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("OliverTroy", "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("OliverTroy", "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("OliverTroy", "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("OliverTroy", "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("OliverTroy", "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("OliverTroy", "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);

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/110342.html

相关文章

  • JavaScript JavaScriptXML——“XPath注意要点

    摘要:对于布尔值类型,如果至少有一个节点与表达式匹配,则求值结果返回,否则返回如果有节点匹配,则返回和方法以上输出与语法匹配的节点数量默认类型结果常量可以自动确定返回结果的类型。 XPath是设计用来在DOM文档中查找节点的一种手段,因而对XML的处理也很重要。很多浏览器实现了这个标准,IE有自己的实现方式。 DOM3级XPath 下面的代码是用来检测浏览器是否支持DOM3级的XPath: ...

    wemallshop 评论0 收藏0
  • JavaScript JavaScriptXML——“XSLT”注意要点

    摘要:中的它不是一种正式的规范,,是的另一表现形式。是第一个支持它的。主要的功能是用来将转换为文档。方法用于取得当前参数的值,参数为命名空间和参数的内部名称。跨浏览器使用这个函数接收两个参数要执行转换的上下文节点和文档对象。 IE中的XSTL 它不是一种正式的规范,, 是XPath的另一表现形式。 IE是第一个支持它的。 简单的XSTL转换 XML文档的方式就是将它们分别加到一个DOM文档中...

    wupengyu 评论0 收藏0
  • JavaScript JavaScriptXML——“XSLT”注意要点

    摘要:中的它不是一种正式的规范,,是的另一表现形式。是第一个支持它的。主要的功能是用来将转换为文档。方法用于取得当前参数的值,参数为命名空间和参数的内部名称。跨浏览器使用这个函数接收两个参数要执行转换的上下文节点和文档对象。 IE中的XSTL 它不是一种正式的规范,, 是XPath的另一表现形式。 IE是第一个支持它的。 简单的XSTL转换 XML文档的方式就是将它们分别加到一个DOM文档中...

    LeexMuller 评论0 收藏0
  • DOM【介绍、HTML中DOM、XMLDOM】

    摘要:的的是一个内存对象树,在浏览器中只保存一份,的修改的内容会直接反应到浏览器中对象在眼中,是由不同类型的节点组成的,这些节点都属性对象。那么,我们需要装载服务器的文件或字符串到中的对象。现在问题就是,和的装载方式是不一样的。 什么是DOM? DOM(Document Object Model)文档对象模型,是语言和平台的中立接口。。 允许程序和脚本动态地访问和更新文档的内容。 为什么要使...

    meislzhua 评论0 收藏0
  • DOM【介绍、HTML中DOM、XMLDOM】

    摘要:的的是一个内存对象树,在浏览器中只保存一份,的修改的内容会直接反应到浏览器中对象在眼中,是由不同类型的节点组成的,这些节点都属性对象。那么,我们需要装载服务器的文件或字符串到中的对象。现在问题就是,和的装载方式是不一样的。 什么是DOM? DOM(Document Object Model)文档对象模型,是语言和平台的中立接口。。 允许程序和脚本动态地访问和更新文档的内容。 为什么要使...

    tomorrowwu 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<