Skip to content
鼓励作者:欢迎打赏犒劳

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>

关键参数说明

  1. resultType
    • ORDERED_NODE_ITERATOR_TYPE:返回节点集合(数组)
    • FIRST_ORDERED_NODE_TYPE:返回单个节点
  2. 命名空间解析器:第三个参数设为null(普通HTML无需命名空间)
  3. 错误处理:捕获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

如有转载或 CV 的请标注本站原文地址