Nokogiri XML Builder создает неожиданный вывод при очистке HTML - PullRequest
2 голосов
/ 22 января 2011

Я довольно новичок в Ruby и мире программирования, поэтому, пожалуйста, потерпите меня.

Моя цель - очистить таблицу и затем сохранить данные в файл XML.Простой скрипт, который я написал, успешно выполняет обе задачи.У меня проблема в том, как сохраняется XML.Он не соответствует XML, который я привык видеть.

Я перерыл немало примеров, учебных пособий и форумов, но пока не нашел решения.

IЯ открыт для любых предложений о лучшем способе получения данных из таблицы, тем более что первые три столбца - это все, что мне действительно нужно.ПОМОГИТЕ !!!

Вот мой сценарий:

require 'nokogiri'
require 'open-uri'

url = "http://www.covers.com/pageLoader/pageLoader.aspx?page=
/data/nba/team/pastresults/2010-2011/team404085.html"
doc = Nokogiri::HTML(open(url))

builder = Nokogiri::XML::Builder.new do |xml|
  xml.root {
    xml.items {
       doc.css('.data').each do |o|
        xml.item_content = o
       end
    }
  }
end

File.open('ATL.xml','w'){|f| f.write builder.to_xml}

puts "Scrape Completed."  

Сохраняется ли он в файле .xml или печатается на экране в Ruby, XML выглядит следующим образом:

<?xml version="1.0"?>
<root>
  <items>
    <item_content=>&lt;table cellpadding="2" cellspacing="1" class="data"&gt;
&lt;tr class="datahead"&gt;
&lt;td width="11%"&gt;Date&lt;/td&gt;&#xD;
    &lt;td width="21%"&gt;Vs&lt;/td&gt;&#xD;
    &lt;td width="18%"&gt;Score&lt;/td&gt;&#xD;
    &lt;td width="27%"&gt;Type&lt;/td&gt;&#xD;
    &lt;td width="13%"&gt;ATL Line&lt;/td&gt;&#xD;
    &lt;td width="10%"&gt;O/U&lt;/td&gt;&#xD;
  &lt;/tr&gt;
&lt;tr class="datarow"&gt;
&lt;td&gt;&#xD;
        01/18/11&lt;/td&gt;&#xD;
      &lt;td&gt;&#xD;
        @ &lt;a href="/pageLoader/pageLoader.aspx?page=/data/nba/team/
team404171.html"&gt;Miami&lt;/a&gt;&#xD;
        &lt;/td&gt;&#xD;
      &lt;td&gt;&#xD;
        W &lt;a href="/pageLoader/pageLoader.aspx?page=/data/nba/
results/2010-2011/boxscore795345.html"&gt;&#xD;
        93-89&lt;/a&gt; (OT)&lt;/td&gt;&#xD;
      &lt;td&gt;&#xD;
        Regular Season&lt;/td&gt;&#xD;
      &lt;td&gt;&#xD;
        W 5.5&lt;/td&gt;&#xD;
      &lt;td&gt;&#xD;
        U 194&lt;/td&gt;&#xD;
    &lt;/tr&gt;

Приведенный выше код является просто фрагментом, так как есть несколько строк.(Всего 44)
Как лучше всего это сделать?

1 Ответ

3 голосов
/ 22 января 2011

Непонятно, что вы хотите получить в качестве вывода; Вы хотите, чтобы HTML из оригинала был включен в XML, или просто содержание HTML? В будущем будет полезно, если вы включите пример того, что вы хотели, вместе с примером проблемы. Давайте решим обе проблемы. Во-первых, мы можем воспроизвести вашу проблему более просто так:

require 'nokogiri'
doc = Nokogiri::XML <<ENDXML
  <root>
    <p class="foo">42</p>
    <p class="bar">99</p>
    <p class="foo">17</p>
  </root>
ENDXML

builder = Nokogiri::XML::Builder.new do |xml|
  xml.items {
    doc.css('.foo').each{ |o| xml.item_content = o }
  }
end    
puts builder.to_xml
#=> <?xml version="1.0"?>
#=> <items>
#=>   <item_content=>&lt;p class="foo"&gt;42&lt;/p&gt;</item_content=>
#=>   <item_content=>&lt;p class="foo"&gt;17&lt;/p&gt;</item_content=>
#=> </items>

Если вы хотели, чтобы содержимое ваших узлов HTML было только в XML, и предполагалось, что вы не хотите, чтобы знак равенства был частью имени тега, то:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.items {
    doc.css('.foo').each{ |o| xml.item_content( o.text ) }
  }
end
puts builder.to_xml
#=> <?xml version="1.0"?>
#=> <items>
#=>   <item_content>42</item_content>
#=>   <item_content>17</item_content>
#=> </items>

Если, с другой стороны, вам нужен необработанный HTML в вашем XML, но вы не хотите всех сущностей, сделайте его блоком CDATA:

builder = Nokogiri::XML::Builder.new do |xml|
  xml.items {
    doc.css('.foo').each{ |o| xml.item_content{ xml.cdata o } }
  }
end
puts builder.to_xml
#=> <?xml version="1.0"?>
#=> <items>
#=>   <item_content><![CDATA[<p class="foo">42</p>]]></item_content>
#=>   <item_content><![CDATA[<p class="foo">17</p>]]></item_content>
#=> </items>

Блок XML CDATA позволяет использовать символы, обычно зарезервированные для разметки XML, без необходимости выражать их как символьные объекты.

...