nokogiriを歩き、xpathで要素を選択するのはかなり簡単です。私はこれの逆を必要とし、意味する:私はする必要があります。 nokogiriノードで.to_xpath
を呼び出して、要素の完全なxpathを取得してレコードに格納します。nokogiriオブジェクトから識別子(例:xpath)を取得する方法は?
誰もがこれを行う方法を知っていますか?
nokogiriを歩き、xpathで要素を選択するのはかなり簡単です。私はこれの逆を必要とし、意味する:私はする必要があります。 nokogiriノードで.to_xpath
を呼び出して、要素の完全なxpathを取得してレコードに格納します。nokogiriオブジェクトから識別子(例:xpath)を取得する方法は?
誰もがこれを行う方法を知っていますか?
最も簡単な方法は、次のようになります。
Nokogiri::CSS.xpath_for node.css_path
EDITは:あなたも試してくださいpath
方法を与えることができます。
ありがとうございます。 Nokogiriはあなたが考えることができるほとんどすべての方法を備えた素晴らしい図書館です。 – Serabe
ちょうどそのcss_pathもトリックを行うことを見た、これは物事をスピードアップする可能性があります。ありがとう! – pduersteler
私は考えることができる最も簡単な方法は、その兄弟の間で、そのノードの数値指標を把握するために、各ノードで(すなわち、バック<html>
に)戻ってルートへの要素パスを構築するためにparent
を使用してprevious_element
ことであろう。ちょうど<body>
と<html>
が1つあるので(必要に応じてNokogiriがあなたの背中の背中にこれらを追加します)、<body>
ノードにヒットしたら親を歩くのを止めることができます。
アルゴリズムは次のようになります。
path = [ ]
は、n
はあなたが既に持っているノードです。s = n
と設定し、s = s.previous_element
をs.nil?
まで呼び出して、繰り返し回数を数えれば、これは兄弟の中でn
の位置になります。ポジションをindex
に入れてください。 XPathの位置は1から始まることに注意してください。path.unshift('*[' + index.to_s + ']')
。p = n.parent
、p
その後<body>
n = p
ではなく、2path.unshift('body').unshift('html')
を。xpath = '/' + path.join('/')
を:
:<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のほとんどのノードへのパスが必要な場合は、ルートから開始して途中のすべてのノードに番号を付けることができます。そうすれば、兄弟を何度も何度も歩くことを避けることができます。私はオフに考えることができる
ありがとう、これを試してみましょう! – pduersteler
@pduersteler:恐らく0/1 /多くの兄弟の番号が正しいことを確認するために、いくつかのテストを追加したいと思うかもしれません。 –
XMLまたはHTML?すべてのノードに 'id'属性がありますか? –
それはhtmlであり、IDノードはありません。これは、動的に置換され、掛け算されるカスタムhtmlタグが使用されているからです。 – pduersteler
あなたはおそらくSerabe'sと一緒に行きたいと思いますが、申し訳ありませんが、私のトンネルビジョンによって、あなたは必要以上に多くの仕事をしました。とにかくあなたのdetailesソリューションのためにありがとう、私はそれが好きです –