Создание HTML-документа с контентом из другого - PullRequest
1 голос
/ 02 декабря 2011

У меня есть документ A , и я хочу создать новый B , используя значения узлов A .

Учитывая A выглядит так ...

<html>
  <head></head>
  <body>
    <div id="section0">
      <h1>Section 0</h1>
      <div>
        <p>Some <b>important</b> info here</p>
        <div>Some unimportant info here</p>
      </div>
    <div>
    <div id="section1">
      <h1>Section 1</h1>
      <div>
        <p>Some <i>important</i> info here</p>
        <div>Some unimportant info here</div>
      </div>
    <div>
  </body>
</html>

При создании документа B я использую метод a.at_css("#section#{n} h1").text для получения данных из тегов A h1, например:

require 'nokogiri'

a = Nokogiri::HTML(html)

Nokogiri::HTML::Builder.new do |doc|
  ...
  doc.h1 a.at_css("#section#{n} h1").text
  ...
end

Итак, есть три вопроса:

  1. Как получить содержимое тегов <p> с сохранением тегов внутри <p>

    В настоящее время, как только я нажму a.at_css("#section#{n} p").text это возвращает простой текст, но это не то, что нужно.

    Если вместо .text я нажму .to_html или .inner_html, html будет отображаться как экранированный. Так я получаю, например, &lt;p&gt; вместо <p>.

  2. Существует ли какой-либо известный верный способ назначения узлов на этапе построения документа? Чтобы я вообще не танцевала с методом text? То есть как назначить doc.h1 узел со значением a.at_css("#section#{n} h1") на этапе сборки?

  3. Какая выгода от метода Nokogiri::Builder.with(...)? Интересно, смогу ли я воспользоваться этим ...

1 Ответ

1 голос
/ 02 декабря 2011
  1. Как получить содержимое тегов <p> с сохранением тегов внутри <p>?

    Используйте .inner_html. Объекты не экранируются при доступе к ним. Они будут сбежать, если вы сделаете что-то вроде builder.node_name raw_html. Вместо этого:

    require 'nokogiri'
    para = Nokogiri.HTML( '<p id="foo">Hello <b>World</b>!</p>' ).at('#foo')
    
    doc = Nokogiri::HTML::Builder.new do |d|
      d.body do
        d.div(id:'content') do
          d.parent << para.inner_html
        end
      end
    end
    
    puts doc.to_html
    #=> <body><div id="content">Hello <b>World</b>!</div></body>
    
  2. Существует ли какой-либо известный истинный способ назначения узлов на этапе создания документа?

    Как и выше, один из способов:

    puts Nokogiri::HTML::Builder.new{ |d| d.body{ d.parent << para } }.to_html
    #=> <body><p id="foo">Hello <b>World</b>!</p></body>
    

    Вуаля! Узел переместился из одного документа в другой.

  3. Какова прибыль метода Nokogiri::Builder.with(...)?

    Это скорее не связано с остальной частью вашего вопроса. Как документация гласит:

    Создание компоновщика с существующим корневым объектом. Это для использования, когда у вас есть существующий документ, который вы хотели бы дополнить методами компоновщика. Созданный контекст построителя начнется с указанного узла root.

    Не думаю, что вам здесь будет полезно.

В общем, я считаю, что Builder удобен при написании большого количества пользовательских узлов с нуля с известной иерархией. Если вы этого не сделаете, вам может быть проще просто создать новый документ и использовать методы DOM для добавления узлов по мере необходимости. Трудно сказать, сколько будет жестко заданных узлов / иерархий в вашем документе по сравнению с процедурно созданными.

Еще одно, альтернативное предложение: возможно, вам следует создать шаблон XML-документа, а затем дополнить его сведениями из другого фрагментированного HTML?

...