Как создать Nokogiri :: XML :: Узел из Nokogiri :: XML :: Builder - PullRequest
0 голосов
/ 21 февраля 2020

Мне нужно заменить узел в документе новым HTML, который я создаю.

Класс узла, который я должен заменить:

Nokogiri::XML::Node

Я создаю мой фрагмент с использованием Nokogiri Builder:

new_node = Nokogiri::XML::Builder.new do |xml|
  xml.table('border' => '1', 'cellpadding' => '1', 'cellspacing' => '1') {
    xml.thead {
      xml.tr {
        battery_test[0..4].each do |head|
          xml.th_ head["inputValue"]
        end
      }
    }
    xml.tbody {
      battery_test.drop(5).each_slice(5) do |row|
        xml.tr {
          row.each do |item|
            xml.td_ item["inputValue"]
          end
        }
      end
    }
  }
end

Но класс new_node равен Nokogiri::XML::Builder.

Как я могу заменить Nokogiri :: XML :: Node на фрагмент, который я создаю вместе со строителем?

1 Ответ

1 голос
/ 23 февраля 2020

Вам не нужно использовать Builder для создания узлов. Nokogiri позволяет несколько способов их определения. Ваш вопрос задан неправильно, так как в нем отсутствует важная информация, но это поможет вам начать:

require 'nokogiri'

doc = Nokogiri::HTML(<<EOT)
<html>
  <head></head>
  <body>
  </body>
</html>
EOT

puts doc.to_html

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >>   <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
# >>   <body>
# >>   </body>
# >> </html>

Я могу добавить таблицу, используя строку, содержащую HTML:

body = doc.at('body')
body.inner_html = "<table><tbody><tr><td>foo</td><td>bar</td></tr></tbody></table>"

puts doc.to_html

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >>   <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
# >>   <body><table><tbody><tr>
# >> <td>foo</td>
# >> <td>bar</td>
# >> </tr></tbody></table></body>
# >> </html>

Измените генерацию строки так, чтобы она содержала HTML, в котором вы нуждаетесь, позвольте Нокогири выполнять тяжелую работу, и все готово. Его легче читать и поддерживать.

inner_html= определяется как:

inner_html=(node_or_tags)

node_or_tags означает, что вы можете пропустить узел, созданный с помощью Builder, вырезанный из другого места в DOM, или строку, содержащую разметку.

Аналогично:

table = Nokogiri::XML::Node.new('table', doc)
table.class # => Nokogiri::XML::Element

table.add_child('<tbody><tr><td>foo</td><td>bar</td></tr></tbody>')
body = doc.at('body')
body.inner_html = table

puts doc.to_html

# >> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
# >> <html>
# >>   <head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
# >>   <body><table><tbody><tr>
# >> <td>foo</td>
# >> <td>bar</td>
# >> </tr></tbody></table></body>
# >> </html>

Обратите внимание, что table является Nokogiri::XML::Element. HTML узлы являются подклассом XML узлов, поэтому не позволяйте этому сбить вас с толку.

Учебники являются хорошей отправной точкой для того, чтобы что-нибудь попробовать с Nokogiri. В этом случае « Изменение HTML / XML Document » является полезным. Также " Шпаргалка " полна совершенства. Наконец, « Вопросы с тегом [nokogiri] » раскрывают все главные вопросы о переполнении стека.

...