循环中的循环不显示所有结果

时间:2014-12-17 10:56:32

标签: ruby xml nokogiri

我有两份文件。 一个是XML:

<sdl>
<group>
    <trans-unit id="57628711-51bd-4e2c-811c-7fa7a5a1cac0">
        <source><g id="67">G_Source_1</g>Source_1</source>
        <seg-source><mrk mtype="seg" mid="4">Seg_Source_1</mrk></seg-source>
        <target><mrk mtype="seg" mid="4"><g id="67">G_Target_1</g>Target_1</mrk></target>
    </trans-unit>
</group>
<group>
        <trans-unit id="7da4f54e-1fa9-46b3-846e-e7745840dcd8">
            <source><g id="970">G_Source_6.1</g>Source_6<g id="971">G_Source_6.2</g></source>
            <seg-source><mrk mtype="seg" mid="921">Seg_Source_6</mrk></seg-source>
            <target><mrk mtype="seg" mid="921"><g id="970">G_Target_6.1</g>Target_6<g id="971">G_Target_6.2</g></mrk></target>
        </trans-unit>
</group>
</sdl>

另一个是制表符分隔的.txt文件。

G_Source_1  G_Target_1
G_Source_6.1    G_Target_6.1
G_Source_6.1    G_Target_6.2

此代码应使用来自XML文件的<g>标记中的所有文本以及TXT文件第1列中的所有文本进行拼写。 并把所有这些结果。

我有以下代码:

glo = File.open(glo_file)
sdlxlff = Nokogiri::XML(open(sdlxlff_file))
sdlxlff.remove_namespaces!
sdlxlff_content = sdlxlff.xpath("//trans-unit")
sdlxlff_content.each do |product| 
  source_sdl = product.xpath("source/g").text
  target_sdl = product.xpath("target//g").text
  mid = product.xpath("target//mrk/@mid")
  glo.each_line do |line|
    content_glo = line.split("\t",2)
    source_glo = content_glo[0]
    target_glo = content_glo[1]
    if source_sdl == source_glo
      puts "same"
      puts source_glo
      puts source_sdl
      puts mid
    end
  end
end

但是只有第一个XML字符串的结果是:

same
G_Source_1
G_Source_1
4

请指点我的问题。 现在,我的代码只比较了第一个<g>标记,并跳过了所有其他标记。

2 个答案:

答案 0 :(得分:1)

您的问题是,如果有多个节点与您的xpath匹配,则在其上调用text会将所有结果汇总在一起:

sdlxlff_content.xpath('//trans-unit/target//g').text
# => "G_Target_1G_Target_6.1G_Target_6.2"

为避免这种情况,您需要在匹配的每个元素上调用text

sdlxlff_content.xpath('//trans-unit/target//g').map { |x| x.text }
# => ["G_Target_1", "G_Target_6.1", "G_Target_6.2"]

因此,您可以将代码更改为以下内容:

sdlxlff_content.each do |product| 
  source_sdl = product.xpath("source/g").map { |x| x.text }
  target_sdl = product.xpath("target//g").map { |x| x.text }
  mid = product.xpath("target//mrk/@mid")
  glo.each_line do |line|
    content_glo = line.split("\t",2)
    source_glo = content_glo[0]
    target_glo = content_glo[1]
    if source_sdl.any? { |x| x == source_glo }
      puts "same"
      puts source_glo
      puts "#{source_sdl}"
      puts mid
    end
  end
end

输出:

same
G_Source_1
["G_Source_1"]
4
same
G_Source_6.1
["G_Source_6.1", "G_Source_6.2"]
921
same
G_Source_6.1
["G_Source_6.1", "G_Source_6.2"]
921

答案 1 :(得分:0)

非常感谢。但我发现了一个问题。 第二次循环第一次运行后我没有关闭文件。 在第一个循环结束前添加glo.close。所有人都成了外出工作。

此致 斯坦尼斯