这里的一些奇怪的示例:

#!/usr/bin/ruby

require 'rubygems'
require 'open-uri'
require 'nokogiri'

print "without read: ", Nokogiri(open('http://weblog.rubyonrails.org/')).class, "\n"
print "with read:    ", Nokogiri(open('http://weblog.rubyonrails.org/').read).class, "\n"

运行此返回:

without read: Nokogiri::XML::Document
with read:    Nokogiri::HTML::Document

如果没有read返回XML,并与它是HTML?该网页被定义为“XHTML过渡”,所以起初我以为引入nokogiri一定是阅读从流OpenURI的“内容类型”,但返回'text/html'

(rdb:1) doc = open(('http://weblog.rubyonrails.org/'))
(rdb:1) doc.content_type
"text/html"

这是什么服务器返回。所以,现在我想弄清楚为什么引入nokogiri将返回两个不同的值。它不会出现被解析文本并使用试探法来确定内容是否为HTML或XML。

同样的事情与ATOM源发生指向该页面:

(rdb:1) doc = Nokogiri.parse(open('http://feeds.feedburner.com/RidingRails'))
(rdb:1) doc.class
Nokogiri::XML::Document

(rdb:1) doc = Nokogiri.parse(open('http://feeds.feedburner.com/RidingRails').read)
(rdb:1) doc.class
Nokogiri::HTML::Document

我需要能够解析页面而不知道它是什么提前,或者HTML或饲料(RSS或ATOM)且可靠地确定哪个是。我问引入nokogiri解析无论是HTML或XML饲料文件的主体,但我看到这些不一致的结果。

我想我可以写一些测试,以确定类型,但后来我跑进的XPath没有找到元素,但常规搜索工作:

(rdb:1) doc = Nokogiri.parse(open('http://feeds.feedburner.com/RidingRails'))
(rdb:1) doc.class
Nokogiri::XML::Document
(rdb:1) doc.xpath('/feed/entry').length
0
(rdb:1) doc.search('feed entry').length
15

我想通的XPath将使用XML,但结果不看守信无论是。

这些测试都做在我的Ubuntu中,但我已经看到了我的MacBook Pro相同的行为。我很想找出我做错了什么,但我还没有看到解析和检索这给了我稳定的结果的例子。谁能告诉我我的方法错误?

有帮助吗?

解决方案

它与方法引入nokogiri的解析方法工作要做。这里的源:

# File lib/nokogiri.rb, line 55
    def parse string, url = nil, encoding = nil, options = nil
      doc =
        if string =~ /^\s*<[^Hh>]*html/i # Probably html
          Nokogiri::HTML::Document.parse(string, url, encoding, options || XML::ParseOptions::DEFAULT_HTML)
        else
          Nokogiri::XML::Document.parse(string, url, encoding, options || XML::ParseOptions::DEFAULT_XML)
        end
      yield doc if block_given?
      doc
    end

的关键是线if string =~ /^\s*<[^Hh>]*html/i # Probably html。当你只是用open,它返回一个对象,不与正则表达式的工作,因此总是返回false。在另一方面,read返回一个字符串,因此它的可能的被视为HTML。在这种情况下,因为它是正则表达式匹配。下面是字符串的开头:

<!DOCTYPE html PUBLIC

在正则表达式匹配“!DOCTYPE”到[^Hh>]*然后匹配的“HTML”,从而假设它是HTML。为什么有人选择了这个正则表达式来确定该文件是HTML是超越我。与此正则表达式,即开始像<definitely-not-html>标签被认为是HTML,但<this-is-still-not-html>被认为是XML文件。你可能最好是关闭此功能哑掉停留,直接调用Nokogiri::HTML::Document#parseNokogiri::XML::Document#parse

其他提示

响应您的问题的这一部分:

  

我想我可以写一些测试,   确定类型,但后来我跑进   XPath的不是寻找元素,但   定期搜索工作:

我已经使用引入nokogiri解析的原子饲料只是遇到了这个问题。这个问题似乎倒在匿名名称空间声明:

<feed xmlns="http://www.w3.org/2005/Atom">

卸下从源XML xmlns声明将使引入nokogiri使用XPath按通常进行搜索。从Feed中移除该声明显然不是一个不错的选择,所以不是我只是删除从文档的命名空间解析之后。例如:

doc = Nokogiri.parse(open('http://feeds.feedburner.com/RidingRails'))
doc.remove_namespaces!
doc.xpath('/feed/entry').length

丑我知道,但它的伎俩。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top