使用Nokogiri解析带有xhtml:link标记的HTML?
我正在使用Nokogiri gem解析HTML数据使用Nokogiri解析带有xhtml:link标记的HTML?,html,ruby,xpath,nokogiri,Html,Ruby,Xpath,Nokogiri,我正在使用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> </htm
$ 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>'
>doc.xpath('/html/body/xhtml:link/div')
Nokogiri::XML::XPath::SyntaxError:未定义的命名空间前缀:/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:在“地图”中
from/var/lib/gems/1.9.1/gems/nokogiri-1.6.2.1/lib/nokogiri/xml/node.rb:150:in'xpath'
起始(irb):95
from/usr/bin/irb:12:in`'
可以找到完整的示例live 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>
另一种方法是手动将该命名空间添加到根文档:
doc.root.add_namespace 'xhtml', 'http://www.w3.org/1999/xhtml'
doc.xpath('/html/body/xhtml:link/div')
虽然这两种方法都会消除错误,但这两种情况下的查询都只会为我返回一个空数组,这与文档中最初包含xmlns
属性时的情况不同。如果您确定同一上下文中没有同名的非固定元素,则可以忽略名称空间。名称空间影响元素和属性名称。如果使用node()
或*
选择它们,则可以在谓词中测试local-name()
,而无需处理名称空间
在您的示例中,您可以选择xhtml:link
元素,方法是选择body
上下文中的所有元素,然后将结果集限制为只有本地名称等于link
的元素:
doc.xpath('/html/body/*[local-name()="link"]/div')
如果在主体中出现不需要的HTML
元素(它们不应该存在,但HTML解析器不在乎它们是否存在),则可能会选择它们。但如果它们出现,它们应该是空元素。不会有一个内部有
的,所以你是安全的。不是真正的问题,但似乎你没有关闭主体
标记。你不能doc.xpath('/html/body/link/div')
它吗?我通过检查Firebug中的元素来获得xpath。这适用于其他文档,但每当元素标记中有冒号“:”时,就会出现上述错误。您是将其解析为HTML还是XML?如果您解析为HTML,那么Nokogiri会剥离名称空间,因此您可以只使用link
。我无法修改现有HTML,因为它来自外部源。那么,我可以向Nokigiri提供名称空间,以便它可以在不修改HTML内容的情况下解析吗?您可以使用轻松删除名称空间。
doc.xpath('/html/body/*[local-name()="link"]/div')