nokogiriがテキストに失敗する

私はHTMLからテキストを抽出しようとしています。

doc = Nokogiri :: HTML( ' ステータス: REGISTERED
')

puts doc.search('//b').first.text
puts doc.search('//b[contains(text(),"Status")]/following-sibling::text()[1]').first.text

the first puts returns Status : But the second puts throws an exception undefined method 'text' for nil:NilClass

なぜ contains は適切に検索しないのですか? または私は間違って何かをしていますか?

0

2 答え

私はあなたがXPathの text 関数について間違っていると思います。 DOM関数とは異なり、すべてのテキストサブノードの連結された文字列は返されません。代わりに、個々のテキストノードを選択します。

あなたの例では、//text()は3つのテキストノードを選択します:

 [" ", " Status :", " REGISTERED "]

あなたが望むかもしれないのは、このXPath式です:

//b/a[contains(text(),"Status")]/../following-sibling::text()[1]

基本的には、親要素( b )まで移動して兄弟テキストノードを取得するよりも、正しいテキストノードを持つ a 要素が見つかります。

1
追加された
これは parent 軸の略語です。
追加された 著者 Daniel Rikowski,
ありがとう...私が /../
追加された 著者 Gaurav Shah,
text()ではなく。 doc.search( '// b [contains(。、 "Status")]/following-sibling :: tex‌ t()')。これはおそらく彼が行っていたものに近いでしょう。
追加された 著者 pguardiario,

"Status:"は実際に 内のテキストノードではなく、 のテキストノードです。

doc.search('//b/a[contains(text(),"Status")]/text()[1]').first.text

私のために働く。

1
追加された
はい、しかし、XPath自体はそれのようには動作しません...それはちょうどノコギリが役に立ちます。 xpathクエリの text()を評価しています。
追加された 著者 d11wtq,
.textはHTMLコンテンツではなく、IMHOで表示されるコンテンツを返します。したがって、( '// b')。text Status を返すので、
追加された 著者 Gaurav Shah,
この場合、 タグの次の兄弟を取得しようとしており、出力は Registered でなければなりません。あなたのコードをどうすればいいですか?
追加された 著者 Gaurav Shah,