繁体   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