当前位置: 首页 > article >正文

跟着 MDN 学 HTML day_51:(深入理解 XPathEvaluator 接口)

在前端开发中我们经常需要对 DOM 树进行复杂的节点查询。虽然 querySelector 和 querySelectorAll 已经能够满足大部分 CSS 选择器需求但在某些场景下我们需要更强大的查询能力比如根据节点的文本内容查找、根据属性是否存在进行匹配、或者执行更复杂的条件组合。这时候XPath 就派上了用场。XPathXML Path Language是一种在 XML 和 HTML 文档中查找信息的语言。在浏览器环境中XPathEvaluator 接口为我们提供了对 XPath 表达式进行编译和求值的能力。今天这篇文章我们将系统学习这个接口的全部核心内容。一、XPathEvaluator 概述XPathEvaluator 是一个基线广泛可用的接口它能够对 XPath 表达式进行编译和求值。这个接口的实现通常集成在 Document 对象中也就是说我们可以直接通过 document 来调用相关方法也可以独立创建 XPathEvaluator 实例来使用。XPath 表达式可以精确地定位 DOM 树中的节点、属性或文本内容比 CSS 选择器提供了更多的灵活性。例如XPath 可以轻松地选择包含特定文本的元素或者根据节点在树中的相对位置进行查询。示例创建一个 XPathEvaluator 实例// 创建一个独立的 XPathEvaluator 实例constevaluatornewXPathEvaluator();console.log(evaluatorinstanceofXPathEvaluator);// true虽然我们可以直接使用 document.evaluate() 方法但独立的 XPathEvaluator 实例在某些模块化或需要独立作用域的场景下更为合适。二、XPathEvaluator.evaluate() 方法定义evaluate() 方法是 XPathEvaluator 接口中最核心的方法。它用于在给定的节点或文档上执行 XPath 表达式并返回一个 XPathResult 对象。语法evaluate(expression,contextNode)evaluate(expression,contextNode,resolver)evaluate(expression,contextNode,resolver,type)evaluate(expression,contextNode,resolver,type,result)参数说明expression字符串形式的 XPath 表达式contextNode作为求值上下文的节点resolver可选用于解析命名空间前缀的对象type可选指定返回结果的类型取自 XPathResult 的常量result可选可复用的结果对象示例使用 evaluate 查询所有 div 元素divXPath example/divdivNumber ofdivs:output/output/divconstevaluatornewXPathEvaluator();// 执行 XPath 表达式查询所有 div 元素constresultevaluator.evaluate(//div,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);// 将匹配的节点数量显示在页面上document.querySelector(output).textContentresult.snapshotLength;在这个例子中我们使用 XPath 表达式 “//div” 来查询文档中所有的元素。evaluate() 方法返回一个 XPathResult 对象通过 snapshotLength 属性获取匹配节点的数量。三、XPathResult 结果类型详解evaluate() 方法的 type 参数决定了返回结果的类型。XPathResult 接口定义了一系列常量来表示不同的结果类型。常用结果类型常量XPathResult.ANY_TYPE任意类型由表达式自然决定XPathResult.NUMBER_TYPE返回数值结果XPathResult.STRING_TYPE返回字符串结果XPathResult.BOOLEAN_TYPE返回布尔值结果XPathResult.ORDERED_NODE_SNAPSHOT_TYPE返回节点快照列表XPathResult.UNORDERED_NODE_ITERATOR_TYPE返回无序节点迭代器XPathResult.FIRST_ORDERED_NODE_TYPE返回第一个匹配节点示例使用不同的结果类型进行查询divclassitemdata-price25商品A/divdivclassitemdata-price30商品B/divdivclassitemdata-price45商品C/divdiv总价格output/output/divconstevaluatornewXPathEvaluator();// 返回数值类型计算所有商品的 price 属性值之和constsumResultevaluator.evaluate(sum(//div[data-price]/data-price),document,null,XPathResult.NUMBER_TYPE);document.querySelector(output).textContentsumResult.numberValue;// 输出100// 返回字符串类型获取第一个商品文本conststringResultevaluator.evaluate(string(//div[classitem][1]),document,null,XPathResult.STRING_TYPE);console.log(stringResult.stringValue);// 输出商品A// 返回布尔类型判断是否存在价格大于 40 的商品constboolResultevaluator.evaluate(boolean(//div[data-price 40]),document,null,XPathResult.BOOLEAN_TYPE);console.log(boolResult.booleanValue);// 输出true掌握不同的结果类型可以让我们更高效地获取需要的数据而不仅仅局限于获取节点列表。四、XPathEvaluator.createExpression() 方法定义createExpression() 方法用于创建一个预编译的 XPath 表达式对象。将表达式预编译后可以多次对其进行求值从而提升性能。这在需要重复执行相同 XPath 查询的场景下非常有用。语法createExpression(expression,resolver)expression字符串形式的 XPath 表达式resolver用于解析命名空间的对象通常可以传入 null示例预编译 XPath 表达式并多次求值divclasssectionpclasstext第一段内容/ppclasstext第二段内容/p/divdivclasssectionpclasstext第三段内容/p/divdiv段落总数output/output/divconstevaluatornewXPathEvaluator();// 预编译 XPath 表达式constexpressionevaluator.createExpression(//p[classtext],null);// 在整个文档上求值constresult1expression.evaluate(document,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);console.log(result1.snapshotLength);// 输出3// 在第一个 section 上求值constfirstSectiondocument.querySelector(.section);constresult2expression.evaluate(firstSection,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);console.log(result2.snapshotLength);// 输出2// 显示总数document.querySelector(output).textContentresult1.snapshotLength;通过预编译表达式我们可以在不同的上下文节点上重复使用同一个表达式对象从而避免了每次都需要重新解析 XPath 字符串的开销。五、XPathEvaluator.createNSResolver() 方法定义createNSResolver() 方法曾经用于创建自定义的命名空间解析器对象。然而这个功能已经被废弃目前该方法直接返回传入的节点本身保留它只是为了兼容性目的。语法createNSResolver(nodeResolver)nodeResolver一个 Node 对象返回值直接返回 nodeResolver 本身示例createNSResolver 的当前行为constevaluatornewXPathEvaluator();constdivdocument.createElement(div);// 调用 createNSResolverconstresolverevaluator.createNSResolver(div);// 现在直接返回传入的节点console.log(resolverdiv);// 输出true由于该方法已经被废弃在新代码中应避免使用它。对于命名空间的解析可以直接使用实现了 lookupNamespaceURI 方法的对象或者使用节点的 lookupNamespaceURI 方法。六、在 XML 文档中使用 XPathEvaluatorXPath 在处理 XML 文档时尤其强大因为 XML 通常包含更复杂的结构和命名空间。虽然现代 Web 开发以 HTML 为主但在处理 SVG、MathML 或纯 XML 数据时XPathEvaluator 依然是不可或缺的工具。示例在 XML 数据中使用 XPath 查询// 创建一个 XML 文档constxmlString?xml version1.0 encodingUTF-8? library book categoryfiction title langenThe Great Gatsby/title authorF. Scott Fitzgerald/author year1925/year /book book categoryfiction title langenTo Kill a Mockingbird/title authorHarper Lee/author year1960/year /book book categorynon-fiction title langenSapiens/title authorYuval Noah Harari/author year2011/year /book /library;constparsernewDOMParser();constxmlDocparser.parseFromString(xmlString,application/xml);constevaluatornewXPathEvaluator();// 查询所有 fiction 类别的书籍标题constresultevaluator.evaluate(//book[categoryfiction]/title/text(),xmlDoc,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);// 输出所有匹配的标题for(leti0;iresult.snapshotLength;i){console.log(result.snapshotItem(i).nodeValue);}// 输出// The Great Gatsby// To Kill a Mockingbird这个例子展示了如何使用 XPathEvaluator 在 XML 文档中执行复杂的条件查询并获取文本内容。在数据驱动的应用中这种技术非常实用。七、XPathEvaluator 与 document.evaluate 的关系在实际开发中我们经常会看到直接使用 document.evaluate() 方法的代码而不是创建 XPathEvaluator 实例。事实上document.evaluate() 是 XPathEvaluator 接口在 Document 上的直接实现。示例两种等价的使用方式// 方式一使用 document.evaluate更常见constresult1document.evaluate(//div,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);// 方式二使用 XPathEvaluator 实例constevaluatornewXPathEvaluator();constresult2evaluator.evaluate(//div,document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);console.log(result1.snapshotLengthresult2.snapshotLength);// true两种方式在功能上是等价的。document.evaluate() 更简洁适合一次性查询。而 XPathEvaluator 实例更独立适合需要预编译表达式或封装查询逻辑的场景。八、实际应用场景XPathEvaluator 在实际开发中有多种应用场景以下是一些常见的例子。场景一根据文本内容查找元素ulli苹果/lili香蕉/lili苹果派/lili橘子/li/ulconstevaluatornewXPathEvaluator();// 查找包含“苹果”文本的 li 元素constresultevaluator.evaluate(//li[contains(text(), 苹果)],document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);for(leti0;iresult.snapshotLength;i){console.log(result.snapshotItem(i).textContent);}// 输出苹果、苹果派这个功能是 CSS 选择器无法直接实现的因为在 CSS 中没有根据文本内容匹配元素的选择器。场景二在自动化测试中定位元素// 在测试脚本中定位具有特定属性的元素functionfindElementByXPath(xpath){constevaluatornewXPathEvaluator();constresultevaluator.evaluate(xpath,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE);returnresult.singleNodeValue;}// 使用示例constbuttonfindElementByXPath(//button[data-testidsubmit-btn]);if(button){button.click();}XPath 在自动化测试框架如 Selenium、Puppeteer中被广泛使用因为它提供了比 CSS 选择器更强大的定位能力。九、注意事项和性能考量虽然 XPath 功能强大但在使用时需要注意以下几点。性能问题XPath 表达式的求值通常比 CSS 选择器慢尤其是在大型 DOM 树上执行复杂表达式时。因此在性能敏感的场景中应优先使用 querySelector 或 querySelectorAll。示例性能对比console.time(CSS Selector);constcssResultdocument.querySelectorAll(div.item p.text);console.timeEnd(CSS Selector);console.time(XPath);constevaluatornewXPathEvaluator();constxpathResultevaluator.evaluate(//div[classitem]/p[classtext],document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE);console.timeEnd(XPath);在大多数情况下CSS 选择器的性能优于 XPath。如果 CSS 选择器能够满足需求应优先使用它。只有在 CSS 选择器无法实现所需逻辑时才使用 XPath。十、总结今天的学习内容聚焦于 XPathEvaluator 接口我们从接口的基本概念开始逐步深入学习了 evaluate() 方法、createExpression() 方法、createNSResolver() 方法以及各种结果类型的使用。通过丰富的示例代码我们看到了 XPath 在复杂 DOM 查询中的强大能力。XPath 表达式为我们提供了一种在文档中定位节点的强大语言而 XPathEvaluator 接口则是在浏览器环境中使用这种语言的桥梁。虽然 CSS 选择器在日常开发中更为常用但掌握 XPath 能够让我们在遇到复杂查询需求时拥有更多的解决方案。希望本篇文章能帮助你理解并掌握 XPathEvaluator 接口的使用为后续的 DOM 操作与自动化测试打下坚实的基础。想要解锁更多HTML 核心标签实战、前端零基础入门干货、开发避坑全指南吗持续关注后续将更新CSS 布局实战、JavaScript 交互基础、全站导航开发等硬核内容带你从新手快速进阶轻松搞定前端开发

相关文章:

跟着 MDN 学 HTML day_51:(深入理解 XPathEvaluator 接口)

在前端开发中,我们经常需要对 DOM 树进行复杂的节点查询。虽然 querySelector 和 querySelectorAll 已经能够满足大部分 CSS 选择器需求,但在某些场景下,我们需要更强大的查询能力,比如根据节点的文本内容查找、根据属性是否存在进…...

基于MCP协议与Graph API实现AI助手无缝集成Outlook邮箱

1. 项目概述与核心价值 最近在折腾AI工作流,发现一个挺有意思的项目: ajaya/outlook-app-mcp 。简单来说,这是一个能让你的AI助手(比如Claude Desktop、Cursor等支持MCP协议的客户端)直接读取和操作你Outlook邮箱的…...

模块四-数据转换与操作——24. 数据分箱

24. 数据分箱 1. 概述 数据分箱(Binning)是将连续变量离散化的过程,将数值范围划分为多个区间,每个区间称为一个"箱"。分箱常用于将连续变量转换为分类变量,便于分析和建模。 import pandas as pd import nu…...

别再乱接电阻了!STM32F407 SWD调试电路设计,从手册到实战的完整避坑指南

STM32F407 SWD调试电路设计:从芯片手册到工程实践的黄金法则 在嵌入式开发领域,调试接口的设计往往被当作"简单连线"而草率处理,直到某天你发现烧录器频繁断开连接、芯片无法识别,或是批量生产中出现随机性下载失败——…...

【工业视觉】基于序列图像动态特征提取的熔炼结晶过程建模与量化分析

1. 工业视觉在熔炼结晶过程中的核心价值 我第一次接触工业视觉在熔炼结晶中的应用是在2018年一个铜冶炼项目。当时工厂老师傅们还在用肉眼观察结晶状态,不仅效率低下,而且不同操作员的判断标准差异能达到15%。这种主观性带来的工艺波动直接影响了产品质量…...

软件测试工程师的“技术外交”:如何搞定开发?

当质量守卫者遇上代码创造者在软件工程的世界里,测试与开发的关系常被比喻为“猫鼠游戏”——一个拼命构建,一个拼命破坏。这种刻板印象背后,隐藏着一条真实而残酷的职场定律:测试工程师的专业价值,一半取决于技术能力…...

Teamcenter: RAC插件开发实战——从环境搭建到BOM报表生成

1. 环境搭建:Target Platform配置实战 第一次接触Teamcenter RAC插件开发时,最让我头疼的就是环境配置。记得当时为了调试一个简单的菜单按钮,整整折腾了两天环境问题。下面分享我验证过的配置流程,帮你避开那些坑。 开发RAC插件需…...

终极指南:PersistentWindows如何彻底解决Windows多显示器窗口管理难题

终极指南:PersistentWindows如何彻底解决Windows多显示器窗口管理难题 【免费下载链接】PersistentWindows fork of http://www.ninjacrab.com/persistent-windows/ with windows 10 update 项目地址: https://gitcode.com/gh_mirrors/pe/PersistentWindows …...

别光抄答案!用Python函数通关Educoder计算思维训练,我总结了这3个实战技巧

用Python函数通关Educoder计算思维训练的3个实战技巧 当你在Educoder平台面对Python函数题目时,是否曾陷入"看懂答案却不会独立解题"的困境?本文将从计算思维的本质出发,分享三个突破函数学习瓶颈的实战技巧。不同于直接提供参考答…...

程序员35岁转型记:我如何成为AI产品经理?

当“质量守卫者”遇见职业天花板如果你是一名软件测试工程师,你一定熟悉这样的场景:凌晨三点还在盯着自动化脚本的运行日志,白天反复和开发争论一个缺陷的定级,周报里写满了用例覆盖率和漏测率,但晋升答辩时评委却问你…...

使用 Taotoken CLI 工具一键配置团队成员的开发环境

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用 Taotoken CLI 工具一键配置团队成员的开发环境 在团队开发中,统一管理大模型 API 的接入配置是一项常见且繁琐的任…...

BQ34Z100-G1电量计配置不求人:用咸鱼EV2400+BqStudio完成电池组参数学习的保姆级教程

BQ34Z100-G1电量计配置实战:从零搭建高精度电池管理系统 在新能源和储能系统蓬勃发展的今天,精确的电池电量计量已成为电池管理系统(BMS)的核心竞争力。德州仪器(TI)的BQ34Z100-G1阻抗跟踪电量计凭借其出色的精度和稳定性,在工业储能、电动工…...

2026企业数字化必看:实在Agent订单数据处理智能助理实战及ERP自动录入教程

进入2026年,全球企业级自动化市场已完成从“流程驱动”向“智能体(Agent)驱动”的范式转移。根据Gartner与IDC在2025年底发布的联合报告显示,超过85%的500强企业已在其核心业务流程中部署了具备自主决策能力的数字员工。在这一背景…...

时间序列分类的能效优化与剪枝策略实践

1. 时间序列分类的能效挑战与剪枝策略概述时间序列分类(Time Series Classification, TSC)作为机器学习的重要分支,在医疗监测、工业设备故障诊断、金融行为分析等领域发挥着关键作用。随着应用场景的复杂化和数据规模的扩大,传统…...

RK3568 Debian系统Docker安装与ARM64容器化部署实战指南

1. 项目概述与核心价值最近在折腾一块基于瑞芯微RK3568的开发板,想在上面跑一些服务,自然而然地就想到了Docker。毕竟,Docker带来的环境隔离和便捷部署,对于嵌入式开发和边缘计算场景来说,简直是“神器”。但当我真正动…...

3分钟搞定!FigmaCN终极中文插件:让英文界面秒变中文的免费神器

3分钟搞定!FigmaCN终极中文插件:让英文界面秒变中文的免费神器 【免费下载链接】figmaCN 中文 Figma 插件,设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面而烦恼吗?专业术…...

Intel Lunar Lake核显架构解析:Xe2-LPG如何重塑轻薄本图形性能

1. 项目概述:一次架构驱动的核显革命最近,Intel Lunar Lake(月亮湖)移动处理器的核显性能数据开始陆续曝光,行业内讨论的热度很高。作为一个长期关注移动平台图形性能的从业者,我第一时间梳理了目前能获取到…...

树莓派Pico上使用Blinka兼容层调用CircuitPython传感器库

1. 项目概述与核心价值如果你手头有一块树莓派 Pico,正在用 MicroPython 开发,但眼馋 CircuitPython 生态里那海量且维护良好的传感器驱动库,比如 Adafruit 官方出品的那些,那么你肯定想过:能不能直接在 MicroPython 里…...

杰理之似于“PO”声,如果切换的时机刚好在音量较高的时候,比较容易出现【篇】

似于“PO”声,如果切换的时机刚好在音量较高的时候,比较容易出现...

从零打造互动徽章:激光切割与电容触摸的软硬件融合实践

1. 项目概述与核心思路如果你参加过技术大会或者创客市集,一定对那些闪烁着酷炫灯光、能与人互动的徽章印象深刻。这类被称为“Badge”的可穿戴设备,早已超越了单纯的身份标识功能,成为了展示技术、创意和社群文化的微型平台。今天要分享的&a…...

TarsCpp协程实现原理:从用户态上下文切换看高性能RPC框架设计

1. 从线程到协程:为什么TarsCpp要拥抱协程?在分布式微服务架构里,我们每天都在和RPC、网络IO、并发处理打交道。传统的多线程模型,一个请求一个线程,逻辑清晰,但线程创建、上下文切换的开销,以及…...

使用Python快速接入Taotoken并切换不同模型进行对话测试

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 使用Python快速接入Taotoken并切换不同模型进行对话测试 本文面向希望快速上手Taotoken平台的Python开发者。我们将通过一份最小化…...

从几何视角解析单层感知机:超平面、分类与学习算法

1. 单层感知机:从几何空间看分类本质 第一次接触单层感知机时,很多人会被各种数学符号绕晕。其实换个角度看,它就是个拿着尺子在高维空间里画分界线的工具。想象你面前有一堆红蓝两色的气球,单层感知机要做的,就是找到…...

长期使用Taotoken聚合API对项目运维复杂度的简化感受

🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 长期使用Taotoken聚合API对项目运维复杂度的简化感受 作为项目维护者,我们团队在过去一段时间里,将多个大模…...

你还在用自然语言写MJ提示词?专业级结构化提示词已进入Token级编排时代:详解::权重、--no冲突域、[]嵌套层级与多模态对齐原理

更多请点击: https://intelliparadigm.com 第一章:自然语言提示词的局限性与结构化范式跃迁 传统自然语言提示(Prompt)虽具备易用性和低门槛优势,但在复杂任务中暴露出显著瓶颈:语义模糊性、上下文敏感性弱…...

Vivado工程实战:在ZCU102上配置MIG控制器时,SLEW属性设置成SLOW还是FAST?

Vivado工程实战:ZCU102平台MIG控制器SLEW属性深度解析 在Xilinx ZCU102开发板上进行DDR4接口设计时,MIG控制器的配置往往成为项目成败的关键。许多工程师能够顺利完成基础配置,却在面对诸如SLEW属性这类"细微"参数时陷入选择困境。…...

Godot游戏开发:模块化系统集成与事件驱动架构实战

1. 项目概述与核心价值如果你正在用Godot引擎做游戏,尤其是那种玩法稍微复杂一点的,比如RPG、策略游戏或者带点模拟经营元素的,那你肯定遇到过这样的问题:每次开新项目,都得从零开始搭一套基础系统。角色状态管理、物品…...

Nornir网络自动化监控插件:集成Sentry实现异常告警与上下文追踪

1. 项目概述:一个为Nornir网络自动化框架量身定制的告警与监控插件 如果你和我一样,长期使用Nornir框架来管理成百上千的网络设备,那你一定遇到过这样的场景:一个精心编写的自动化任务在测试环境跑得飞快,一旦放到生产…...

Agent监控管理工具agenttop:实现自动化任务的可观测性与可控性

1. 项目概述与核心价值最近在开源社区里,我注意到一个名为vicarious11/agenttop的项目开始受到一些开发者的关注。乍一看这个标题,你可能会和我最初的反应一样:这又是一个“Agent”相关的工具,现在这类项目多如牛毛。但当我花时间…...

AI驱动的代码冻结守护者:开源项目xcf如何提升软件发布质量

1. 项目概述:当AI遇上代码冻结,一个开源协作范式的诞生最近在开源社区里,一个名为CodeFreezeAI/xcf的项目引起了我的注意。乍一看这个标题,可能会让人有些困惑:“CodeFreeze” 通常指的是软件开发流程中的“代码冻结”…...