遍历nokogiri并使用xpath选择元素相当容易。我需要反之亦然,这意味着:我需要在nokogiri节点上调用.to_xpath
以获得元素的完整xpath以将其存储在记录中。
有人知道怎么做吗?
我能想到的最简单的方法是:
Nokogiri::CSS.xpath_for node.css_path
EDIT:你也可以试试path
方法
我能想到的最简单的事情是使用parent
在每个节点上构建一个返回根(即返回<html>
)和previous_element
的元素路径,以找出该节点在其兄弟姐妹中的数字索引。因为只有一个<body>
和<html>
(如果有必要,Nokogiri会在你背后为你添加这些),你可以在到达<body>
节点后停止向上走。
算法如下:
- 初始化:
path = [ ]
,n
是你已经有的节点。 - 设置
s = n
并调用s = s.previous_element
直到s.nil?
,并计算您进行了多少次迭代,这将为您提供n
在其兄弟姐妹中的位置。把位置放在index
中。请记住,XPath位置是基于一个的。 - 存储新的路径组件:
path.unshift('*[' + index.to_s + ']')
. - 设置
p = n.parent
,如果p
不是<body>
,则设置n = p
并返回步骤2。 - 添加我们知道的最终组件:
path.unshift('body').unshift('html')
. 构建XPath表达式:
xpath = '/' + path.join('/')
如果有这样的HTML:
<ul><li>a</li><li><b>b<em>c</em></b></li></ul>
和<em>c</em>
的开始节点,您将得到如下所示的XPath:
/html/body/*[1]/*[2]/*[1]/*[1]
不是很漂亮,但至少过程相当简单,并且生成的XPath将是唯一的。
如果你需要到DOM中大多数节点的路径,那么你可以从根开始,并在向下的过程中对所有节点进行编号。这样你就可以避免一次又一次地遛兄弟姐妹了。