1

XML タグをネストしており、を使用してタグExternalIdProductXMLの値を含める必要があります。ProductPageURLXML::Twig

<Products>
    <Product>
      <ExternalId>317851</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>316232</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>13472</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
</Products>

期待される結果:

<Products>
    <Product>
      <ExternalId>PF317851</ExternalId>
      <ProductPageUrl>317851</ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>PF316232</ExternalId>
      <ProductPageUrl>316232</ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>PF13472</ExternalId>
      <ProductPageUrl>13472</ProductPageUrl>
    </Product>
    </Products>

私は以下のロジックを使用していますXML::Twig:

my $twig = XML::Twig->new( 
        twig_handlers => {      
            'Product/ExternalId' => sub {
                $_->prefix( 'PF' );
            },
             'Product/ProductPageUrl' => sub {
                $_->set_text($_->get('Product/ExternalId'));
            }, 
                
        },
        pretty_print => 'indented',
    keep_encoding => 1,
    )->parsefile($xml_path_filename )->print_to_file($xml_path_filename);

コードを簡単にする方法を教えてください。期待した結果を達成できません。

4

2 に答える 2

2

get最初のコードには 2 つの問題があります。まず、XML::Twig::Elt メソッドではないと思います。次に、最初にExternalIdテキストにプレフィックスを付けてから、(プレフィックスを付けたら) それを使用して update を試みますProductPageUrl。それはうまくいきません。Productこの場合、id データを取得してから両方のサブ要素を更新する、タグ用の単一のハンドラーを使用する方がよいと思います。

出力が変更された場合に更新しやすいように、テストとして作成されたソリューションを次に示します。

#!/usr/bin/perl

use strict;
use warnings;

use Test::More tests => 1;

use XML::Twig;

# in and expected are in the DATA section, separated by 2 \n
my( $in, $expected)= do { local $/="\n\n"; <DATA>};

my $t= XML::Twig->new( twig_handlers => { Product => \&update_product },
                       keep_spaces => 1,
                     )     
                 ->parse( $in);

is( $t->sprint, $expected, "one test to rule them all");

sub update_product
  { my( $t, $product)= @_;
    my $id= $product->field( 'ExternalId');
    $product->first_child( 'ExternalId')->prefix( 'PF');
    $product->first_child( 'ProductPageUrl')->set_text( $id);
  }

__DATA__
<Products>
    <Product>
      <ExternalId>317851</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>316232</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>13472</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
</Products>

<Products>
    <Product>
      <ExternalId>PF317851</ExternalId>
      <ProductPageUrl>317851</ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>PF316232</ExternalId>
      <ProductPageUrl>316232</ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>PF13472</ExternalId>
      <ProductPageUrl>13472</ProductPageUrl>
    </Product>
</Products>
于 2013-01-17T17:14:30.930 に答える
2

1 つの方法を次に示します。

use warnings;
use strict;
use XML::Twig;

my $twig = XML::Twig->new( 
    twig_handlers => {      
        Product => \&prod,
    },
    pretty_print => 'indented',
    keep_encoding => 1,
);

$twig->parse(q(
<Products>
    <Product>
      <ExternalId>317851</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>316232</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
    <Product>
      <ExternalId>13472</ExternalId>
      <ProductPageUrl></ProductPageUrl>
    </Product>
</Products>
));

$twig->print();

sub prod {
    my ($t, $prod) = @_;
    my $extid = $prod->first_child('ExternalId');
    my $id = $extid->text();
    $extid->prefix('PF');
    my $url = $prod->first_child('ProductPageUrl');
    $url->set_text($id);
}

出力

<Products>
  <Product>
    <ExternalId>PF317851</ExternalId>
    <ProductPageUrl>317851</ProductPageUrl>
  </Product>
  <Product>
    <ExternalId>PF316232</ExternalId>
    <ProductPageUrl>316232</ProductPageUrl>
  </Product>
  <Product>
    <ExternalId>PF13472</ExternalId>
    <ProductPageUrl>13472</ProductPageUrl>
  </Product>
</Products>
于 2013-01-17T17:00:07.870 に答える