Синтаксический анализ содержимого элементов абзаца с помощью Nokogiri

#ruby-on-rails #ruby #xml #regex #nokogiri

#ruby-on-rails #ruby #xml #регулярное выражение #nokogiri

Вопрос:

Я хотел бы знать, как правильно анализировать блок содержимого с помощью Nokogiri:

У меня есть несколько документов для анализа, где они изначально содержали формат, в котором каждый основной контейнер был <p> . Основные фрагменты информации внутри каждого из них, как ни странно, разделены <font> тегами.

Фактически стандартный образец <p> содержимого содержит следующее и является типичным примером (некоторые содержат намного больше содержимого, некоторые намного меньше):

 <p>
  <font size="5" face="Arial, Helvetica, sans-serif" color="#00CCAA" class="">
    <font color="#AAFF33" class="">
      October 10, 1990 - Maybe a Title
    </font>- 
    <font size="4" class="">
      Some long text here.         
      <font color="#66CC00" class="">
        <a href="SourceTitle/date.pdf">[Blah Blah, October 27, 1982 p. 2</a>
        ]
      </font>. 
      More content. 
      <font color="#00FF33" class="">[Another Source, 1971, issue 01/4]
      </font>. 
    </font>
    <font size="5" face="Arial, Helvetica, sans-serif" color="#00CCAA" class="">
      <font color="#AAFF33" class=""><font size="4" color="#00CCAA" class="">
        Another fantastic article. 
        <a href="SourceTitle/Date.pdf">[Some Source, October 4, p.6]</a>
      </font>
    </font>
  </font>
</font>
</p>
  

По сути, атрибут «размер шрифта» — это то, что отличает каждый компонент в статье. Основными точками для извлечения являются ПЕРВЫЕ <font size ="5"... (то есть дата статьи и основной заголовок, если указан заголовок) теги, а затем фактическое содержимое.

В настоящее время у меня есть все фрагменты абзаца с: doc.xpath('//p').each do |node|

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

Комментарии:

1. Не могли бы вы привести пример целевого документа, который вы хотите получить?

2. К сожалению, я не могу привести реальный пример данных, поскольку это частная информация, содержащаяся в содержимом. Я извлек пару «строк» информации для вашего обзора в контексте всего текста: j.mp/qbpJnh

3. Происходит какое-то недоразумение. Я имею в виду пример документа, который вы хотите получить в качестве результата

4. Извините, @WarHog вывод действительно не был важен сам по себе, поскольку я могу просто разобрать фрагменты. Я могу использовать регулярное выражение, что угодно, чтобы извлекать строки и тому подобное. Мне просто нужно было знать о xpathing внутри xpath, так как было около 4 часов утра, и мой мозг был слишком затуманен, чтобы больше думать … 😉

Ответ №1:

Это поможет вам начать работу?

 >> doc.xpath('//p').each do |node|
..     puts node.xpath("font[@size='5']/font").first.content.strip
..   end #=> 0
October 10, 1990 - Maybe a Title
  

Создайте аналогичные выражения для других частей, которые вам нужны, и все готово 🙂

Комментарии:

1. Хорошо, очень быстро, генерируемые объекты являются Nokogiri::XML::Element , однако content в этом случае я получаю неопределенный метод. Хм, пока не вижу быстрого ответа.

2. Извините, отсюда трудно сказать. Поиграйте с IRB, проверьте элементы, используйте другие методы самоанализа (например instance_methods ) и т. Д. Вероятно, это просто мелочь…

3. Верно, играл здесь. Оказывается, к каждому шрифту был применен неожиданный «цветной» стиль, который фактически отличает «заголовок» от остальных. Это приводит к возврату некоторых нулевых значений. Я изучаю, как использовать как шрифт size , так и color now в строке соответствия. Т.Е. я бы предположил, что это было бы что-то вроде "font[@size='5',@color='FFFF33']/font" , но пока нет кубиков.

4. И какого черта, я больше не могу использовать grep Google с такими фразами, как: "@size=" and "@color=" nokogiri and xpath >:(

5. Так и должно быть font[@size='5' and @color='#FFFF33']/font .