簡體   English   中英

使用Nokogiri解析帶有xhtml:link標記的HTML?

[英]Using Nokogiri to parse HTML with xhtml:link tag?

我正在使用Nokogiri gem來解析HTML數據。

$ gem list nokogiri

*** LOCAL GEMS ***

nokogiri (1.6.2.1)

示例HTML是:

<html>
  <body>
    <xhtml:link>
      <div>
    Some content.
      </div>
    </xhtml:link>
  </body>
</html>

我正進入(狀態

>>  doc.xpath('/html/body/xhtml:link/div')
Nokogiri::XML::XPath::SyntaxError: Undefined namespace prefix: /html/body/xhtml:link/div
    from /var/lib/gems/1.9.1/gems/nokogiri-1.6.2.1/lib/nokogiri/xml/node.rb:159:in `evaluate'
    from /var/lib/gems/1.9.1/gems/nokogiri-1.6.2.1/lib/nokogiri/xml/node.rb:159:in `block in xpath'
    from /var/lib/gems/1.9.1/gems/nokogiri-1.6.2.1/lib/nokogiri/xml/node.rb:150:in `map'
    from /var/lib/gems/1.9.1/gems/nokogiri-1.6.2.1/lib/nokogiri/xml/node.rb:150:in `xpath'
    from (irb):95
    from /usr/bin/irb:12:in `<main>'

完整的實時HTML頁面示例可在此處找到

如何避免此錯誤?

您需要將XML命名空間(在示例中為xhtml )添加到根元素中,以便Nokogiri能夠識別它,除非您這樣做,否則Nokogiri將忽略它並出現該錯誤。

您可以這樣操作:

<html xmlns:xhtml="http://www.w3.org/1999/xhtml">
    <body>
        <xhtml:link>
            <div>Some content.</div>
        </xhtml:link>
    </body>
</html>

另請參閱答案。

根據評論更新

我查看了Nokogiri文檔,發現了兩種解決方法,一種是傳遞名稱空間:

doc.xpath('/html/body/xhtml:link/div', 'xhtml' => 'http://www.w3.org/1999/xhtml')

另一個方法是手動將該名稱空間添加到根文檔中:

doc.root.add_namespace 'xhtml', 'http://www.w3.org/1999/xhtml'
doc.xpath('/html/body/xhtml:link/div')

盡管兩種方法都可以使錯誤靜音,但兩種情況下的查詢都只為我返回一個空數組,這與xmlns屬性最初包含在文檔中時的情況不同。

如果確定在相同的上下文中不存在具有相同名稱的未前綴元素,則可以忽略名稱空間。 命名空間影響元素和屬性名稱 如果使用node()*選擇它們,則可以在謂詞中測試local-name() ,而不必處理名稱空間。

在您的示例中,可以通過選擇body上下文中的所有元素來選擇xhtml:link元素,然后將結果集限制為僅具有本地名稱等於link

doc.xpath('/html/body/*[local-name()="link"]/div')

如果不需要的HTML <link>元素出現在正文中,則可以選擇它們(它們永遠不應該在其中,但是HTML解析器不在乎)。 但是,如果它們發生,它們應該是空元素。 里面永遠不會有<div> ,所以很安全。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM