Замените image src в разметке vml глобально доступными изображениями с помощью Nokogiri.

Можно ли найти разметку Outlook через Capybara/Nokogiri?

Учитывая следующую разметку (теги erb <% %> обрабатываются в обычный HTML)

...
<div>
<!--[if gte mso 9]>
    <v:rect
        xmlns:v="urn:schemas-microsoft-com:vml" fill="true" stroke="false"
        style="width:<%= card_width %>px;height:<%= card_header_height %>px;"
    >
        <v:fill type="tile"
            src="<%= avatar_background_url.split('?')[0] %>"
            color="<%= background_color %>" />
        <v:textbox inset="0,0,0,0">
<![endif]-->
<div>

Как я могу получить список тегов <v:fill ../>? (или, в конце концов, как я могу получить весь комментарий, если поиск тега внутри условного комментария является проблемой)

Я пробовал следующее

doc.xpath('//v:fill')

*** Nokogiri::XML::XPath::SyntaxError Исключение: ОШИБКА: Неопределенный префикс пространства имен: //v:fill

Нужно ли как-то регистрировать пространство имен vml?

РЕДАКТИРОВАТЬ - следуя подходу @ThomasWalpole

doc.xpath('//comment()').each do |comment_node|
  vml_node_match = /<v\:fill.*src=\"(?<url>http\:[^"]*)"[^>]*\/>/.match(comment_node)
  if vml_node_match
    original_image_uri = URI.parse(vml_node_match['url'])
    vml_tag = vml_node_match[0]
    handle_vml_image_replacement(original_image_uri, comment_node, vml_tag)
  end

Затем мой handle_vml_image_replacement вызывает следующий replace_comment_image_src

def self.replace_comment_image_src(node:, comment:, old_url:, new_url:)
  new_url = new_url.split('?').first # VML does not support URL with query params
  puts "Replacing comment src URL in #{comment} by #{new_url}"
  node.content = node.content.gsub(old_url, new_url)
end

Но тогда кажется, что комментарий на самом деле больше не является «комментарием», и иногда я вижу HTML, как если бы он был экранирован... Скорее всего, я использую неправильный метод для изменения текста комментария с помощью Nokogiri?


person Cyril Duchon-Doris    schedule 16.02.2018    source источник
comment
Вы можете установить пространство имен в качестве параметров xpath(), но проблема заключается в комментарии. Содержимое комментария недоступно через xpath().   -  person sschmeck    schedule 16.02.2018
comment
Как я могу получить доступ к комментарию? не удалось найти много документации по комментариям в nokogiri?   -  person Cyril Duchon-Doris    schedule 16.02.2018
comment
Вы можете получить доступ к комментариям с помощью XPath //comment(), однако nokogiri IIRC не анализирует содержимое комментариев на дополнительные узлы (это просто текст), поэтому вы не сможете запрашивать определенные узлы в комментарии.   -  person Thomas Walpole    schedule 17.02.2018
comment
Эй, спасибо за совет @ThomasWalpole, но я изо всех сил пытаюсь найти способ заменить атрибут тега src, не испортив все это ...   -  person Cyril Duchon-Doris    schedule 19.02.2018
comment
@CyrilDuchon-Doris Возможно, вы хотите native_content= вместо content=. Последний экранирует устанавливаемый текст, а первый нет.   -  person Thomas Walpole    schedule 19.02.2018


Ответы (1)


Вот окончательный код, который я использовал для своего перехватчика электронной почты, спасибо @Thomas Walpole и @sschmeck за помощь на этом пути.

Моя цель состояла в том, чтобы заменить изображения (ссылку на локальный хост) в разметке VML глобально доступными изображениями для тестирования с помощью таких сервисов, как MOA или Litmus.

doc.xpath('//comment()').each do |comment_node|
  # Note : cannot capture beginning of tag, since it might span across several lines
  src_attr_match = /.*src=\"(?<url>http\:[^"]*)"[^>]*\/>/.match(comment_node)
  next unless src_attr_match
  original_image_uri = URI.parse(src_attr_match['url'])
  handle_comment_image_replacement(original_image_uri, comment_node)
end

WHich позже вызывает (после выбора стратегии замены URL в зависимости от типа исходного изображения):

def self.replace_comment_image_src(node:, old_url:, new_url:)
  new_url = new_url.split('?').first
  node.native_content = node.content.gsub(old_url, new_url)
end
person Cyril Duchon-Doris    schedule 10.03.2018