2010-12-09 37 views
1

我有下面的示例XML:如何只有一個字符串喂引入nokogiri

<all> 
    <houses> 
     <reg info='<root><h level="2" i="1"> something </h><root>' 
      other="test" 
      something 
     </reg> 
    </houses> 
</all> 

我想分析的<reg>標籤的info酒店所提供的XML,但我不知道如何餵養屬於Nokogiri的info屬性的內容。

這是我現在有:

doc = Nokogiri::HTML(open-uri(mylink)) 
node = doc.xpath(//houses/reg) 
puts node[0]['info'].class #string 
#content of info property as string. This is what I want to feed to nokogiri as xml 
puts node[0]['info'].text 

我怎樣才能做到這一點?

+0

通常使用HTML解析器來解析XML將是錯誤的,但在這種情況下,它有助於解析HTML解析更爲寬鬆。請參閱我對Nokogiri目前行爲的回答。 – 2016-06-03 20:14:22

回答

3

您需要獲取info屬性的文本,並使用GCI類來避開HTML。然後,您可以將該字符串輸入到Nokogiri::HTML,並將其解析。像這樣的東西。

require "nokogiri" 
require "open-uri" 
require "cgi" 

doc = Nokogiri::HTML(open-uri("http://example.com/foo.xml")) 
node = doc.xpath("//houses/reg") 
info_string = CGI.unescapeHTML(node[0]['info']) 
info_doc = Nokogiri::XML(info_string) 
# Now you can have a Nokogiri document from that attribute. 
0
require 'nokogiri' 

xml = "<all> 
    <houses> 
     <reg info='<root><h level=\"2\" i=\"1\"> something </h><root>' 
      other=\"test\" 
      something 
     </reg> 
    </houses> 
</all>" 

doc = Nokogiri::HTML(xml) 
node = doc.xpath('//houses/reg') 
puts node[0]['info'].class #string 
puts node[0]['info'] 

inner_xml = node[0]['info'] 
inner_doc = Nokogiri::XML(inner_xml) 
puts inner_doc.xpath('root/h')[0].text 
-1

node[0].attr('info')給你信息的屬性值

+0

這段代碼沒有解析就不會做任何事情,不正確的解析會導致'info`屬性被破壞。您的答案需要展示如何制定可行的解決方案。 – 2016-06-03 20:04:19

0

這裏有一些事情需要注意:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<all> 
    <houses> 
    <reg info='<root><h level="2" i="1"> something </h><root>' 
      other="test" 
      something 
    </reg> 
    </houses> 
</all> 
EOT 

doc.errors # => [#<Nokogiri::XML::SyntaxError: Unescaped '<' not allowed in attributes values>, #<Nokogiri::XML::SyntaxError: attributes construct error>, #<Nokogiri::XML::SyntaxError: Couldn't find end of Start Tag reg line 3>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: root line 3 and reg>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: root line 3 and houses>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: houses line 2 and all>, #<Nokogiri::XML::SyntaxError: Premature end of data in tag all line 1>] 
doc.at('reg')['info'] # => "" 
puts doc.to_xml 

# >> <?xml version="1.0"?> 
# >> <all> 
# >> <houses> 
# >>  <reg info=""/><root><h level="2" i="1"> something </h><root>' 
# >>   other="test" 
# >>   something 
# >>  </root> 
# >> </root> 
# >> </houses> 
# >> </all> 

解析XML通常應當使用Nokogiri::XML作爲XML是一個嚴格的規範。此標記格式不正確,Nokogiri會正確標記錯誤,並且由於格式錯誤會嘗試修復並繼續解析。

使用Nokogiri::HTML放鬆了繮繩,並讓解析器對它所看到的更加寬大;是出了名寫的不好HTML所以引入nokogiri嘗試更寬鬆:

doc = Nokogiri::HTML(<<EOT) 
<all> 
    <houses> 
    <reg info='<root><h level="2" i="1"> something </h><root>' 
      other="test" 
      something 
    </reg> 
    </houses> 
</all> 
EOT 

doc.errors # => [#<Nokogiri::XML::SyntaxError: Tag all invalid>, #<Nokogiri::XML::SyntaxError: Tag houses invalid>, #<Nokogiri::XML::SyntaxError: error parsing attribute name>, #<Nokogiri::XML::SyntaxError: Tag reg invalid>] 
doc.at('reg')['info'] # => "<root><h level=\"2\" i=\"1\"> something </h><root>" 
puts doc.to_xml 


# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
# >> <html><body> 
# >> <all> 
# >> <houses> 
# >>  <reg info='&lt;root&gt;&lt;h level="2" i="1"&gt; something &lt;/h&gt;&lt;root&gt;' other="test" something> 
# >> </reg></houses> 
# >> </all> 
# >> </body></html> 

注意如何引入nokogiri現在:

  • 正確HTML編碼的info
  • 正確提取和info內容進行解碼的內容。

我不確定Nokogiri的行爲是否因最初問題而改變,但是v.1.6.7.2中的當前行爲無需使用CGI即可正確處理解碼。

0

這裏有一些事情需要注意:

require 'nokogiri' 

doc = Nokogiri::XML(<<EOT) 
<all> 
    <houses> 
    <reg info='<root><h level="2" i="1"> something </h><root>' 
      other="test" 
      something 
    </reg> 
    </houses> 
</all> 
EOT 

doc.errors # => [#<Nokogiri::XML::SyntaxError: Unescaped '<' not allowed in attributes values>, #<Nokogiri::XML::SyntaxError: attributes construct error>, #<Nokogiri::XML::SyntaxError: Couldn't find end of Start Tag reg line 3>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: root line 3 and reg>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: root line 3 and houses>, #<Nokogiri::XML::SyntaxError: Opening and ending tag mismatch: houses line 2 and all>, #<Nokogiri::XML::SyntaxError: Premature end of data in tag all line 1>] 
doc.at('reg')['info'] # => "" 
puts doc.to_xml 

# >> <?xml version="1.0"?> 
# >> <all> 
# >> <houses> 
# >>  <reg info=""/><root><h level="2" i="1"> something </h><root>' 
# >>   other="test" 
# >>   something 
# >>  </root> 
# >> </root> 
# >> </houses> 
# >> </all> 

解析XML通常應當使用Nokogiri::XML作爲XML是一個嚴格的規範。此標記格式不正確,Nokogiri會正確標記錯誤,並且由於格式錯誤會嘗試修復並繼續解析。

使用Nokogiri::HTML放鬆了繮繩,並讓解析器對它所看到的更加寬大;是出了名寫的不好HTML所以引入nokogiri嘗試更寬鬆:

doc = Nokogiri::HTML(<<EOT) 
<all> 
    <houses> 
    <reg info='<root><h level="2" i="1"> something </h><root>' 
      other="test" 
      something 
    </reg> 
    </houses> 
</all> 
EOT 

doc.errors # => [#<Nokogiri::XML::SyntaxError: Tag all invalid>, #<Nokogiri::XML::SyntaxError: Tag houses invalid>, #<Nokogiri::XML::SyntaxError: error parsing attribute name>, #<Nokogiri::XML::SyntaxError: Tag reg invalid>] 
doc.at('reg')['info'] # => "<root><h level=\"2\" i=\"1\"> something </h><root>" 
puts doc.to_xml 


# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> 
# >> <html><body> 
# >> <all> 
# >> <houses> 
# >>  <reg info='&lt;root&gt;&lt;h level="2" i="1"&gt; something &lt;/h&gt;&lt;root&gt;' other="test" something> 
# >> </reg></houses> 
# >> </all> 
# >> </body></html> 

注意如何引入nokogiri現在:

  • 正確HTML編碼的info
  • 正確提取和info內容進行解碼的內容。
  • 由於將內容解析爲HTML,因此將HTML中的XML封裝在HTML <html><body>標記中。

要提取固定的XML需要剝開幾個層次:

puts doc.at('all').to_xml 

# >> <all> 
# >> <houses> 
# >>  <reg info="&lt;root&gt;&lt;h level=&quot;2&quot; i=&quot;1&quot;&gt; something &lt;/h&gt;&lt;root&gt;" other="test" something=""> 
# >> </reg></houses> 
# >> </all> 

我不知道,如果引入nokogiri的行爲改變,因爲這個問題原本問,但在v.1.6當前的行爲。 7.2無需使用CGI即可正確處理解碼。

相關問題