2

このXMLスニペットでは、一部のブロックのUIDのデータを置き換える必要があります。実際のファイルには、100を超える同様のブロックが含まれています。

に基づいてサブセットを抽出することはできましたが、のテキストがxxxxに設定されている場合name="Track (Timeline)"は、のデータも使用して、このサブセットを必要な特定のブロックに減らすのに苦労しています。<TrackID>name="Track (TimeLine)"<TrackID>0x1200UID

私は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>
4

2 に答える 2

2

xpath の使用:

//StructuralMetadata

StructuralMetadataXML 内のすべての要素を選択します。先頭の二重スラッシュは、ドキュメント内に表示されるノードを選択することを意味します。

ただし、すべてのノードが必要なわけではありません。必要なノードを述語でフィルタリングできます。

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

これにより、 valueを持つ属性と content を持つ子要素を持つすべての要素が選択さStructuralMetadataれます。nameTrack (TimeLine)TrackID0x1200

要素に興味があるUIDので、式をさらに絞り込むことができます。

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

この式は、上記の述語に一致する要素UIDの子であるすべての要素に一致します。StructuralMetadata

これを使用する:

require 'nokogiri'

# Parse the document, assuming xml_file is a File object containing the XML
doc = Nokogiri::XML(xml_file)

# I'm assuming there is only one element in the document that matches
# the criteria, so I'm using at_xpath
node = doc.at_xpath('//StructuralMetadata[@name="Track (TimeLine)" and TrackID="0x1200"]/UID')

# At this point, doc contains a representation of the xml, and node points to
# the UID node within that representation. We can update the contents of
# this node
node.content = 'XXX'

# Now write out the updated XML. This just writes it to standard output,
# you could write it to a file or elsewhere if needed
puts doc.to_xml
于 2012-04-04T19:19:38.883 に答える
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 ファイルなどを保存できます。

于 2012-04-04T11:06:02.350 に答える