Xpath in JavaScript
test html
<p>title</p>
<ul class="list a" id="list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
</ul>
<footer>footer</footer>
function xpath(path, parent = document) {
const r = document.evaluate(
path,
parent,
null,
XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
null
);
const len = r.snapshotLength;
const list = [];
for (let i = 0; i < len; i++) list.push(r.snapshotItem(i));
return list;
}
const r = xpath(`//ul[contains(@class, 'list')]/li/text()`);
console.log(r);
child
const r = xpath(`//ul[contains(@class, 'list a')]/li`);
for (const i of r)
console.log( xpath("./text()", i) );
跳过列表第一个
// xpath(`//ul/li/text()`).slice(1,Number.MAX_VALUE)
xpath(`//ul/li[position()>1]/text()`)
列表第一个
xpath(`//ul/li[1]/text()`);
列表最后一个
xpath(`//ul/li[last()]/text()`);
第一个和最后一个
xpath(`//ul/li[position()=1 or position()=last()]/text()`)
child slice
xpath(`//ul/li[position()>1 and position()<last()]/text()`) // 2,3
列表过滤
<ul class="list a" id="list">
<li><a href="">1</a></li>
<li>2</li>
<li><a href="">3</a></li>
</ul>
xpath(`//ul/li[./a]/a/text()`) // 1,3
xpath(`//ul/li[not(./a)]/text()`) // 2
列表过滤2
<ul>
<li>1</li>
<li>2</li>
<li>23</li>
<li>332</li>
</ul>
xpath(`//ul/li/text()[contains(., '2')]`) // 2,23,332
xpath(`//ul/li[contains(./text(), '2')]/text()`) // 和上面一样
xpath(`//ul/li/text()[.='2']`) // 2
xpath(`//ul/li[./text()='2']/text()`)// 和上面一样
get attr
xpath(`//ul/@class`)
find id
xpath(`//ul[@id="list"]`);
starts-with
xpath(`//ul[starts-with(@id,'lis')]`);
兄弟元素
<p>title</p>
<ul class="list a" id="list"></ul>
<footer>footer</footer>
xpath(`//ul/preceding::p[1]`)
xpath(`//ul/preceding::*[1]`)
xpath(`//ul/following::footer[1]`)
xpath(`//ul/following::*[1]`)
指定后代
<ul class="list a" id="list">
<li><a href="">1</a></li>
<li><a href="">2</a></li>
</ul>
// xpath(`//ul/li/a`)
xpath(`//ul/descendant::a`)
parent
xpath(`//ul/parent::body`)
xpath(`//ul/parent::*`)
See alse: