
16-xpath
xpath使用示例
工具类
javascript
/**
* 执行XPath查询
* @param {string} xpath - XPath表达式
* @param {Node} [context=document] - 查询上下文节点
* @param {boolean} [singleNode=false] - 是否只返回单个节点
* @returns {Array|Node|null} 匹配的节点数组/单个节点/null
*/
function xpathQuery(xpath, context = document, singleNode = false) {
const resultType = singleNode
? XPathResult.FIRST_ORDERED_NODE_TYPE
: XPathResult.ORDERED_NODE_ITERATOR_TYPE;
try {
const result = document.evaluate(
xpath,
context,
null,
resultType,
null
);
if (singleNode) {
return result.singleNodeValue;
}
const nodes = [];
let node;
while ((node = result.iterateNext())) {
nodes.push(node);
}
return nodes;
} catch (e) {
console.error("XPath查询错误:", e);
return singleNode ? null : [];
}
}
使用示例
html
<!DOCTYPE html>
<html>
<body>
<div class="container">
<h1>示例页面</h1>
<ul id="list">
<li>苹果</li>
<li class="highlight">香蕉</li>
<li>橙子</li>
</ul>
</div>
<script>
// 此处插入上述xpathQuery函数代码
// 示例1:查询所有<li>元素
const allItems = xpathQuery("//li");
console.log("所有水果:", allItems); // 输出3个<li>节点
// 示例2:查询带highlight类的元素
const highlighted = xpathQuery("//li[contains(@class, 'highlight')]");
console.log("高亮项:", highlighted[0].textContent); // 输出"香蕉"
// 示例3:在特定上下文(#list)中查询
const contextNode = document.getElementById("list");
const firstItem = xpathQuery("li[1]", contextNode, true);
console.log("第一项:", firstItem.textContent); // 输出"苹果"
// 示例4:直接获取单个节点
const title = xpathQuery("//h1", document, true);
console.log("标题:", title.textContent); // 输出"示例页面"
</script>
</body>
</html>
关键参数说明
- resultType:
ORDERED_NODE_ITERATOR_TYPE
:返回节点集合(数组)FIRST_ORDERED_NODE_TYPE
:返回单个节点
- 命名空间解析器:第三个参数设为
null
(普通HTML无需命名空间) - 错误处理:捕获XPath语法错误并返回空值
常见XPath表达式示例
表达式 | 说明 |
---|---|
//div | 所有div元素 |
//ul/li | 所有ul的直接子li |
//li[1] | 每组父元素中的第一个li |
//*[@id="list"] | ID为list的元素 |
//*[@class="title"] | class为title的元素 |
//li[contains(@class,"highlight")] | class包含highlight的li |
获取元素xpath路径
javascript
// 鼠标悬停事件处理函数
function mouse_over(event) {
var element = event.target; // 获取鼠标悬停的元素
if (event.ctrlKey) { // 如果同时按下了 Ctrl 键
var xpath = getXPath(element); // 获取当前元素的 XPath 路径
console.log(xpath); // 打印 XPath 路径到控制台
}
element.style.border = "1px solid red"; // 添加红色边框
}
// 鼠标移出事件处理函数
function mouse_out(event) {
var element = event.target; // 获取鼠标移出的元素
element.style.border = ""; // 移除边框
}
// 获取元素的 XPath 路径
function getXPath(element) {
if (element.id !== "") { // 如果元素具有 ID 属性
return '//*[@id="' + element.id + '"]'; // 返回格式为 '//*[@id="elementId"]' 的 XPath 路径
}
if (element === document.body) { // 如果当前元素是 document.body
return "/html/body"; // 返回 '/html/body' 的 XPath 路径
}
var index = 1;
const childNodes = element.parentNode ? element.parentNode.childNodes : []; // 获取当前元素的父节点的子节点列表
var siblings = childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
if (sibling === element) { // 遍历到当前元素
// 递归调用,获取父节点的 XPath 路径,然后拼接当前元素的标签名和索引
return (
getXPath(element.parentNode) +
"/" +
element.tagName.toLowerCase() +
"[" + index + "]"
);
}
if (sibling.nodeType === 1 && sibling.tagName === element.tagName) { // 遍历到具有相同标签名的元素
index++; // 增加索引值
}
}
}
// 添加鼠标悬停事件监听器
document.addEventListener("mouseover", mouse_over);
// 添加鼠标移出事件监听器
document.addEventListener("mouseout", mouse_out);
常用的api
获取文本
js
node.nodeType === Node.TEXT_NODE ? node.nodeValue : node.textContent
- 对于文本节点使用 nodeValue
- 对于元素节点使用 textContent
获取属性值
text
//img/@src