2013-01-06 49 views
3

参考页:http://www.ncbi.nlm.nih.gov/pubmed/?term=NS044283[GR]&dispmax=200&report=xml从HTML中提取XML?

XML嵌入在返回的HTML页面的<pre>标记下。 我可以提取<pre>标记的内容,但我无法将其正确转换为XML。 我尝试使用NodeSet类的to_xml方法,但似乎行结尾(\n)搞乱了解析。

这里是我的代码片段:

url = "http://www.ncbi.nlm.nih.gov/pubmed/?term=NS044283[GR]&dispmax=200&report=xml" 
doc = Nokogiri::XML(open(url)) 
pre = doc.xpath('//pre') 
xml = pre.to_xml 
contents = Nokogiri::XML(xml) 
articles = contents.xpath('\\PubmedArticle') 
(article = []) 
+0

'to_xml'告诉Nokogiri将节点内容转换为XML,导致它重新编码'<', '>'和其他“非法”字符,然后您必须解码。使用'text'和Nokogiri将解码编码字符,然后您可以将其解析为XML。 –

回答

4

既然你要使用引入nokogiri反正解析它,只需调用content而不是to_xml

require 'nokogiri' 
require 'open-uri' 
url = "http://www.ncbi.nlm.nih.gov/pubmed/?term=NS044283[GR]&dispmax=200&report=xml" 
doc = Nokogiri::XML(open(url)) 
pre = doc.xpath('//pre') 
xml = "<root>" + pre.text + "</root>" 
contents = Nokogiri::XML(xml) 
articles = contents.css('PubmedArticle') 
puts contents.css('ArticleTitle').map{|x| x.content}.count 
=> 25 
+1

而不是'pre.first.content', pre.text'。它应该是相同的结果。 'pre.text.size => 387471'或'pre.first.content.size => 387471' –

+0

是的,与#文本相同的结果 –

+0

'articles.count或.size'只给我'1'。应该有20+,对应于''标签的数量。我错过了什么吗?令人敬畏的回应btw! – RailinginDFW

-1

嵌入式XML是无效的(HTML转义)。尝试取消转义它

... 
xml = CGI.unescapeHTML(pre.to_xml) # or CGI.unescapeHTML(pre.to_s) 
... 
+1

没有必要使用'CGI.unescapeHTML'。相反,使用'pre.text'和Nokogiri会解码这些实体并将它们变回正规的标签。例如:'pre.text [0..50] => “\ n \ n

1

被检索的文件不是有效的XML或HTML。对创造它的人感到羞耻。

这里的第一个200个字符,呈现在他们的部分有些混乱:

require 'open-uri' 
url = "http://www.ncbi.nlm.nih.gov/pubmed/?term=NS044283[GR]&dispmax=200&report=xml" 
puts open(url).read[0..200] 

返回:

<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 
<pre> 
&lt;PubmedArticle&gt; 
    &lt;Medl 

幸运的是,或者,也许坚决,引入nokogiri工作围绕通过与稍微宽松格式不正确的HTML。