-2

私は次のようなxmlファイルを持っています

     <?xml version="1.0"?>
     <product = "AAA">
     <shell name = "110">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>
     </shell name>
     </product>
     <product = "AAA">
     <shell name = "310">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>
     </shell name>
     </product>
     <product = "BBB">
     <shell name = "10">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>

     </shell name>
     </product>
     <product = "BBB">
      <shell name = "10010">
         <style = "0300" size ="3"/>
         <style = "2030" size ="3"/>
         <style = "8003" size ="1"/>
         <style = "09003" size ="3"/>
     </shell name>
     </product>
     <product = "BBB">
      <shell name = "110">
         <style = "0300" size ="3"/>
         <style = "2030" size ="3"/>
         <style = "8003" size ="1"/>
         <style = "09003" size ="3"/>
     </shell name>
     </product>

同じ製品のシェルをクラブ化して、次のような出力が得られるようにするスクリプトを作成したい

     <?xml version="1.0"?>
     <product = AAA>
     <shell name = "110">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>
     </shell name>
    <shell name = "310">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>
     </shell name>
   </product>
     <product = BBB>
    <shell name = "10">
         <style = "000" size ="3"/>
         <style = "200" size ="3"/>
         <style = "800" size ="1"/>
         <style = "0900" size ="3"/>
     </shell name>
     <shell name = "10010">
         <style = "0300" size ="3"/>
         <style = "2030" size ="3"/>
         <style = "8003" size ="1"/>
         <style = "09003" size ="3"/>
     </shell name>
     <shell name = "110">
         <style = "0300" size ="3"/>
         <style = "2030" size ="3"/>
         <style = "8003" size ="1"/>
         <style = "09003" size ="3"/>
     </shell name>
     </product>

私がどのように進めることができるかについてのアイデアはありますか?文字列を検索することを考えていました</product>

 <product = "AAA">

しかし、どうすれば2番目の発生に到達できますか。ファイルを読み取って特定の文字列の出現回数をカウントする方法を知っていますが、特定の文字列の2番目の出現に到達する方法を誰かが助けることができますか?

4

2 に答える 2

2

XMLファイルを整形式に変更しました。

<?xml version="1.0"?>
<products>
     <product id="AAA">
     <shell name="110">
         <style n="000" size="3"/>
         <style n="200" size="3"/>
         <style n="800" size="1"/>
         <style n="0900" size="3"/>
     </shell>
     </product>
     <product id="AAA">
     <shell name="310">
         <style n="000" size="3"/>
         <style n="200" size="3"/>
         <style n="800" size="1"/>
         <style n="0900" size="3"/>
     </shell>
     </product>
     <product id="BBB">
     <shell name="10">
         <style n="000" size="3"/>
         <style n="200" size="3"/>
         <style n="800" size="1"/>
         <style n="0900" size="3"/>

     </shell>
     </product>
     <product id="BBB">
      <shell name="10010">
         <style n="0300" size="3"/>
         <style n="2030" size="3"/>
         <style n="8003" size="1"/>
         <style n="09003" size="3"/>
     </shell>
     </product>
     <product id="BBB">
      <shell name="110">
         <style n="0300" size="3"/>
         <style n="2030" size="3"/>
         <style n="8003" size="1"/>
         <style n="09003" size="3"/>
     </shell>
     </product>
</products>

次に、XML::XSH2を使用して処理しました。

open 1.xml ;
for //product {
    my $id = @id ;
    mv shell append //product[@id=$id][1] ;
}
rm //product[not(shell)] ;
save --backup ;
于 2012-09-13T10:03:19.320 に答える
1

XML :: Twigを使用すると、次のように実行できます。

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_handlers => { product => \&product },
                pretty_print => 'indented',
              )
         ->parsefile_inplace( 'so_conc.xml');

sub product
  { my( $t, $product)= @_;
    my $prev_product=  $product->prev_sibling( 'product') || return;
    if( $product->id eq $prev_product->id)
      { $product->first_child( 'shell')->move( last_child => $prev_product);
        $product->delete;
      }
    else
      { $t->flush_up_to( $prev_product); }
  }

このflush_up_to行は、一度に1つの製品のみがメモリに保持され、の呼び出しと組み合わせてparsefile_inplace元のファイルを更新することを保証するためにあります。

于 2012-09-13T10:37:11.853 に答える