javascript基础学习系列三百五十六:单个节点结果

如果指定了快照结果类型(无论有序还是无序),都必须使用 snapshotItem()方法和 snapshotLength 属性获取结果,如以下代码所示:

let result = xmldom.evaluate("employee/name", xmldom.documentElement, null,
                      XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    if (result !== null) {
      for (let i = 0, len=result.snapshotLength; i < len; i++) {
        console.log(result.snapshotItem(i).tagName);
}
}

这个例子中,snapshotLength 返回快照中节点的数量,而 snapshotItem()返回快照中给定位
置的节点(类似于 NodeList 中的 length 和 item())。

单个节点结果

XPathResult.FIRST_ORDERED_NODE_TYPE 结果类型返回匹配的第一个节点,可以通过结果的 singleNodeValue 属性获取。比如:

let result = xmldom.evaluate("employee/name", xmldom.documentElement, null,
                      XPathResult.FIRST_ORDERED_NODE_TYPE, null);
    if (result !== null) {
      console.log(result.singleNodeValue.tagName);
}

与其他查询一样,如果没有匹配的节点,evaluate()返回 null。如果有一个匹配的节点,则要使
用 singleNodeValue 属性取得该节点。这对 XPathResult.FIRST_ORDERED_NODE_TYPE 也一样。

简单类型结果

使用布尔值、数值和字符串 XPathResult 类型,可以根据 XPath 获取简单、非节点数据类型。这 些结果类型返回的值需要分别使用 booleanValue、numberValue 和 stringValue 属性获取。对于 布尔值类型,如果至少有一个节点匹配 XPath 表达式,booleanValue 就是 true;否则,booleanValue 为 false。比如:

let result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.BOOLEAN_TYPE, null);
    console.log(result.booleanValue);

在这个例子中,如果有任何节点匹配"employee/name",booleanValue 属性就等于 true。
对于数值类型,XPath 表达式必须使用返回数值的 XPath 函数,如 count()可以计算匹配给定模式 的节点数。比如:

let result = xmldom.evaluate("count(employee/name)", xmldom.documentElement, null, XPathResult.NUMBER_TYPE, null);
    console.log(result.numberValue);

以上代码会输出匹配"employee/name"的节点数量(比如 2)。如果在这里没有指定 XPath 函数, numberValue 就等于 NaN。
对于字符串类型,evaluate()方法查找匹配 XPath 表达式的第一个节点,然后返回其第一个子节 点的值,前提是第一个子节点是文本节点。如果不是,就返回空字符串。比如:

let result = xmldom.evaluate("employee/name", xmldom.documentElement, null, XPathResult.STRING_TYPE, null);
console.log(result.stringValue); 

这个例子输出了与"employee/name"匹配的第一个元素中第一个文本节点包含的文本字符串。

默认类型结果

所有 XPath 表达式都会自动映射到特定类型的结果。设置特定结果类型会限制表达式的输出。不过, 可以使用 XPathResult.ANY_TYPE 类型让求值自动返回默认类型结果。通常,默认类型结果是布尔值、 18 数值、字符串或无序节点迭代器。要确定返回的结果类型,可以访问求值结果的 resultType 属性,如 下例所示:

let result = xmldom.evaluate("employee/name", xmldom.documentElement, null, 19 XPathResult.ANY_TYPE, null);
if (result !== null) {
  switch(result.resultType) {
    case XPathResult.STRING_TYPE:
// 处理字符串类型 break;
case XPathResult.NUMBER_TYPE: 21 // 处理数值类型
break;

命名空间支持

对于使用命名空间的 XML 文档,必须告诉 XPathEvaluator 命名空间信息,才能进行正确求值。 处理命名空间的方式有很多,看下面的示例 XML 代码:

    <?xml version="1.0" ?>
    <wrox:books xmlns:wrox="http://www.wrox.com/">
<wrox:book>
<wrox:title>Professional JavaScript for Web Developers</wrox:title> <wrox:author>Nicholas C. Zakas</wrox:author>
case XPathResult.BOOLEAN_TYPE: // 处理布尔值类型
break;
case XPathResult.UNORDERED_NODE_ITERATOR_TYPE: // 处理无序节点迭代器类型
break;
default:
// 处理其他可能的结果类型
}
 }

使用 XPathResult.ANY_TYPE 可以让使用 XPath 变得更自然,但在返回结果后则需要增加额外的
判断和处理。

       </wrox:book>
      <wrox:book>
        <wrox:title>Professional Ajax</wrox:title>
        <wrox:author>Nicholas C. Zakas</wrox:author>
        <wrox:author>Jeremy McPeak</wrox:author>
        <wrox:author>Joe Fawcett</wrox:author>
      </wrox:book>
    </wrox:books>

第一种处理命名空间的方式是通过 createNSResolver()方法创建 XPathNSResolver 对象。这 个方法只接收一个参数,即包含命名空间定义的文档节点。对上面的例子而言,这个节点就是 document 元素wrox:books,其 xmlns 属性定义了命名空间。为此,可以将该节点传给 createNSResolver(), 然后得到的结果就可以在 evaluate()方法中使用:

let nsresolver = xmldom.createNSResolver(xmldom.documentElement);
    let result = xmldom.evaluate("wrox:book/wrox:author",
                   xmldom.documentElement, nsresolver,
                   XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    console.log(result.snapshotLength);

把 nsresolver 传给 evaluate()之后,可以确保 XPath 表达式中使用的 wrox 前缀能够被正确理 解。假如不使用 XPathNSResolver,同样的表达式就会导致错误。
第二种处理命名空间的方式是定义一个接收命名空间前缀并返回相应 URI 的函数,如下所示:

   let nsresolver = function(prefix) {
      switch(prefix) {
        case "wrox": return "http://www.wrox.com/";
// 其他前缀及返回值 }
};
let result = xmldom.evaluate("count(wrox:book/wrox:author)", xmldom.documentElement, nsresolver, XPathResult.NUMBER_TYPE, null);
    console.log(result.numberValue);

在并不知晓文档的哪个节点包含命名空间定义时,可以采用这种定义命名空间解析函数的方式。只 要知道前缀和 URI,就可以定义这样一个函数,然后把它作为第三个参数传给 evaluate()。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值