本文介绍如何用单条 xpath 表达式实现“优先匹配某条件,若不存在则回退到另一条件”,并确保仅返回文档中第一个匹配节点(按文档顺序),避免重复执行 evaluate 调用。
在 XPath 中,|(联合运算符)会合并两个节点集,并自动按文档顺序去重排序。因此,表达式 //*[@selected]/@value|//text() 本身已将所有匹配的 @value 属性节点和文本节点混合后按其在 DOM 中的实际位置升序排列。此时只需在外层添加 [1] 即可精准获取整个联合结果中的第一个节点——这正是“优先取 [@selected]/@value,无则取 /
/text() 中最早出现者”的语义实现。
✅ 正确写法(XPath 1.0 兼容,浏览器原生支持):
(//*[@selected]/@value|//text())[1]
该表达式在 document.evaluate 中可直接使用,无需 JavaScript 分支逻辑:
function xpathFirst(path) {
const result = document.evaluate(
path,
document,
null,
XPathResult.FIRST_ORDERED_NODE_TYPE,
null
);
return result.singleNodeValue;
}
const value = xpathFirst('(//*[@selected]/@value|//text())[1]');
// 若存在带 selected 属性的元素,返回其 value 属性值(字符串);
// 否则返回文档中第一个文本节点(Text 对象,需 .nodeValue 获取内容)⚠️ 注意事项:
(//*[@selected]/@value, //input/@placeholder, //div/text())[1]
逗号表示序列拼接(保持顺序,不排序),更符合“严格优先级”语义。
? 总结:对于双条件 fallback 场景,(A|B)[1] 是 XPath 1.0 下简洁、高效、标准兼容的最佳实践;它利用联合运算符的文档顺序特性,以声明式语法替代命令式分支,显著提升可读性与可维护性。