нокогири заменить

Я разбираю HTML-документ и пытаюсь заменить изображение src. Кажется, он делает то, что я хочу, когда я пытаюсь сделать это в консоли, однако в моей модели он, похоже, не сохраняет его. Теперь я не уверен, что я делаю неправильно со способом сохранения в Rails (я пытаюсь обновить поле содержимого и заменить внешние изображения локальными) или он использует nokogiri, но не сохраняет результат с использованием метода set_attribute

Все остальное он делает отлично.

  before_save :replace_zemanta_images

  def replace_zemanta_images
    doc = Nokogiri::HTML(content)
    unless doc.css('div.zemanta-img').blank?
      doc.css('div.zemanta-img img').each do |img|
        io = open(URI.parse(img[:src]))
        if photos.find_by_data_remote_url(img[:src]).blank?
          photo = photos.build(:data => io, :data_remote_url => img[:src])
          img.set_attribute('src', photo.data.url(:original)) #doesn't work!
        end
      end
    end
  end

person holden    schedule 17.01.2011    source источник


Ответы (2)


Я предполагаю, что content является атрибутом вашей модели.

Когда вы делаете img.set_attribute, вы обновляете атрибут в объекте Nokogiri::XML::Element, но это не обновляет текст content.

В конце вашего метода вам нужно будет добавить что-то вроде:

self.content = doc.to_s
person mikej    schedule 17.01.2011
comment
Отлично, я знал, что что-то упускаю из виду! Спасибо - person holden; 17.01.2011
comment
Я также заметил, что Nokogiri, кажется, добавляет ‹HTML doctype› и тег body... независимо от того, был он там или нет. Любая идея, как предотвратить это? - person holden; 18.01.2011
comment
Часто есть небольшие различия между HTML-кодом, который вы загружаете в Nokogiri, и HTML-кодом, который вы получаете, выполняя doc.to_s. Это следствие того, что он проходит через синтаксический анализатор, и, насколько мне известно, избежать этого невозможно. - person mikej; 18.01.2011
comment
Вы, вероятно, захотите использовать doc = Nokogiri::HTTP::DocumentFragment.parse(content) DocumentFragment не оборачивает его тегами ‹html› или ‹body›, он принимает его как есть. - person JackChance; 03.02.2016

JackChance упомянул использовать Nokogiri::HTTP::DocumentFragment.parse(content) здесь для фрагмента (если вам не нужны теги DOCTYPE/HTML/BODY), мне не повезло с этим, поскольку мой исходный HTML был фрагментом, а не целым документом.

В итоге я использовал что-то вроде этого: html = Nokogiri::HTML.fragment для первоначального преобразования фрагмента строки HTML в объект Nokogiri без ненужных тегов.

Затем, когда мы используем img.set_attribute, мы можем преобразовать обратно html.to_s

person ck-bamf    schedule 27.09.2016