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:

原文地址:https://www.cnblogs.com/ajanuw/p/14371514.html