使用Nokogiri和正则表达式解析Ruby XML文档中的编码标签

4

我正在尝试使用Nokogiri和Ruby解析嵌套标签的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>

在这种情况下,我只需要嵌入标签中的单词“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

在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>),这样应该只剩下内容元素了。将结果数组中的内容元素连接在一起形成一个字符串。

请注意,输出略有不同,因为两个标记之间有一个额外的 DX


1

<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

这将输出以下节点,显示Nokogiri正确地重新创建了该片段:

<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.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接