Разбор закодированных тегов в документе Ruby XML с использованием Nokogiri и regex - PullRequest
4 голосов
/ 24 декабря 2011

Я пытаюсь проанализировать XML с тегами, встроенными в теги, например, используя Nokigiri и Ruby:

<seg>Trennmesser <ph>&lt;I.FIGREF ITEM=&quot;3&quot; FORMAT=&quot;PARENTHESIS&quot;&gt;</ph><bpt i="1">&lt;I.FIGTARGET TARGET=&quot;CIADDAJA&quot;&gt;</bpt><ept i="1">&lt;/I.FIGREF&gt;</ept></seg>

В этом случае мне понадобится только слово "Trennmesser", а не внутри встроенных тегов.

Во втором примере:

<seg>Hilfsmittel <ph>&lt;F34@Z7@Lge&gt;</ph>X <ph>&lt;F0&gt;</ph>= 0,5mm zwischen    Beschleunigerwalze <ph>&lt;F34@Z7@Lge&gt;</ph>D<ph>&lt;F0&gt;</ph> und Trennmesser schieben.</seg>

Слова внутри закрытых тегов /ph и открытых ph также интересны, поэтому регулярному выражению потребуется извлечь строку "Hilfsmittel 0,5mm zwischen Beschleunigerwalze und Trennmesser schieben. "и откажитесь от всего остального.

Я также загрузил часть документа здесь:
http://pastebin.com/Q8CdnASz

Ответы [ 2 ]

1 голос
/ 21 сентября 2012

Содержимое внутри тегов <ph> было закодировано для сохранения зарезервированных символов < и >.

. Чистый способ справиться с этим - позволить Nokogiri преобразовать эти фрагменты обратно в XML.:

require 'nokogiri'

doc = Nokogiri::XML('<seg>Trennmesser <ph>&lt;I.FIGREF ITEM=&quot;3&quot; FORMAT=&quot;PARENTHESIS&quot;&gt;</ph><bpt i="1">&lt;I.FIGTARGET TARGET=&quot;CIADDAJA&quot;&gt;</bpt><ept i="1">&lt;/I.FIGREF&gt;</ept></seg>')

ph = Nokogiri::XML::DocumentFragment.parse(doc.at('seg ph').content)
puts ph.to_xml

, который выводит следующий узел, показывая, что Нокогири правильно воссоздал этот фрагмент:

<I.FIGREF ITEM="3" FORMAT="PARENTHESIS"/>

Для извлечения текста внутри тега <seg>:

doc.at('//seg/text()').text
=> "Trennmesser "

При работе с HTML или XML никогда не стоит предполагать, что регулярное выражение будет лучшим путем для извлечения чего-либо.И HTML, и XML слишком нерегулярны и «гибки» (где «гибкость» означает, что она часто раздражающе искажена или определена совершенно уникальными и неожиданными способами.

Чтобы получить полный контент внутри тега <seg> во втором вопросе:

require 'nokogiri'

doc = Nokogiri::XML('<seg>Hilfsmittel <ph>&lt;F34@Z7@Lge&gt;</ph>X <ph>&lt;F0&gt;</ph>= 0,5mm zwischen    Beschleunigerwalze <ph>&lt;F34@Z7@Lge&gt;</ph>D<ph>&lt;F0&gt;</ph> und Trennmesser schieben.</seg>')

seg = Nokogiri::XML::DocumentFragment.parse(doc.at('seg').content)
puts seg.content

Какие выходы:

Hilfsmittel @Z7@Lge>X = 0,5mm zwischen    Beschleunigerwalze @Z7@Lge>D und Trennmesser schieben.
1 голос
/ 24 декабря 2011

Попробуйте это в irb

require 'nokogiri'
x = Nokogiri::XML.parse('<seg>Hilfsmittel <ph>&lt;F34@Z7@Lge&gt;</ph>X <ph>&lt;F0&gt;</ph>= 0,5mm zwischen    Beschleunigerwalze <ph>&lt;F34@Z7@Lge&gt;</ph>D<ph>&lt;F0&gt;</ph> und Trennmesser schieben.</seg>')
x.xpath('//seg').children.reject {|x| x.element?}.join {|x| x.content}

для меня это выводы

=> "Hilfsmittel X = 0,5mm zwischen    Beschleunigerwalze D und Trennmesser schieben."

Идея заключается в том, что мы перебираем дочерние элементы тега <seg>, отвергая те, которые сами являются элементами (<ph>), которые должны оставлять только элементы содержимого. Возьмите результирующий массив и объедините элементы содержимого в одну строку.

Обратите внимание, что вывод немного отличается от того, что вы описали, потому что между двумя тегами есть дополнительные D и X.

...