使用具有多个搜索元素的Nokogiri

时间:2012-04-04 08:54:24

标签: ruby nokogiri

在这个XML片段中,我需要替换某些块的UID中的数据。实际文件包含100多个类似的块。

虽然我已经能够根据name="Track (Timeline)"提取子集,但我仍然努力通过使用<TrackID>中的数据将name="Track (TimeLine)"中的数据减少到我需要的特定块。 } <TrackID>的文字为0x1200,然后将UID设为xxxx。

我是Nokogiri的新手,虽然我编写测试脚本,但我认为自己不是程序员。

<StructuralMetadata key="06.0E.2B.34.02.53.01.01.0D.01.01.01.01.01.3B.00" length="116" name="Track (TimeLine)">
    <EditRate>25/1</EditRate>
    <Origin>0</Origin>
    <Sequence>32-04-25-67-E7-A7-86-4A-9B-28-53-6F-66-74-65-6C</Sequence>
    <TrackID>0x1200</TrackID>
    <TrackName>Softel VBI Data</TrackName>
    <TrackNumber>0x17010101</TrackNumber>
    <UID>34-C1-B9-B9-5F-07-A4-4E-8F-F4-53-6F-66-74-65-6C</UID>
</StructuralMetadata>
<StructuralMetadata key="06.0E.2B.34.02.53.01.01.0D.01.01.01.01.01.3B.00" length="116" name="Track (TimeLine)">
    <EditRate>25/1</EditRate>
    <Origin>0</Origin>
    <Sequence>35-12-2D-86-E6-74-0B-4C-B4-24-53-6F-66-74-65-6C</Sequence>
    <TrackID>0x1300</TrackID>
    <TrackName>Softel VBI Data</TrackName>
    <TrackNumber>0x0</TrackNumber>
    <UID>37-0C-80-34-4C-8D-CE-41-85-F3-53-6F-66-74-65-6C</UID>
</StructuralMetadata>

2 个答案:

答案 0 :(得分:2)

使用xpath:

//StructuralMetadata

将选择XML中的所有StructuralMetadata元素。开始时的双斜杠意味着选择节点出现在文档中的任何位置。

您不希望所有节点,您可以使用谓词过滤所需的节点:

//StructuralMetadata[@name="Track (TimeLine)" and TrackID="0x1200"]

这将选择StructuralMetadata属性值为name的所有Track (TimeLine)元素,以及内容为TrackID的{​​{1}}子元素。

由于您对0x1200元素感兴趣,可以进一步细化表达式:

UID

此表达式将匹配与上述谓词匹配的//StructuralMetadata[@name="Track (TimeLine)" and TrackID="0x1200"]/UID 元素子元素的所有UID元素。

使用它:

StructuralMetadata

答案 1 :(得分:1)

解决这个问题的一个很好的方法是使用'map reduce'编程风格,它可以获取大量的事物并将其缩小并将其组合到您所追求的结果中。具体而言,Array#findArray#select对此类问题非常有用。看看这个例子:

require 'nokogiri'
xml = Nokogiri::XML.parse(File.read "sample.xml")
element = xml.css('StructuralMetadata').find { |item|
  item['name'] == "Track (TimeLine)" and item.css('TrackID').text == "0x1200"
}
puts element.to_xml

这个小程序首先使用CSS选择器来获取文档中的所有<StructuralMetadata>元素。它返回一个数组,我们可以使用Array#find方法过滤到我们想要的数组。 Array#select是它的堂兄,它返回所有匹配对象的数组,而不是它碰巧找到的第一个对象。

在块中,我们有一个测试来检查<StructuralMetadata>标签是否是我们追求的标签。然后它将element.to_xml字符串放入控制台,这样您就可以看到它作为命令行脚本运行时发现了哪些内容。现在您可以找到该元素,您可以按照常规方式对其进行修改,并保存一个新的XML文件或其他任何内容。