使用 XML::Twig 复制 XML 值 [英] Copy XML value using XML::Twig
问题描述
我有嵌套的 XML 标签,需要使用 XML 将
.Product
XML 中的 ExternalId
值转换为 ProductPageURL
标签::Twig
I have nested XML tags and need to have the value of ExternalId
in Product
XML to a ProductPageURL
tag using XML::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
使用以下逻辑:
I have using the below logic using 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);
你能告诉我如何使代码更容易吗?我无法达到预期的结果.
Could you let me know how to make the code easier? I am not able to achieve the expected result.
推荐答案
你的初始代码有两个问题:首先我不认为 get
是一个 XML::Twig::Elt 方法.然后您首先为 ExternalId
文本添加前缀,然后(一旦添加前缀)尝试使用它来更新 ProductPageUrl
.那行不通.在这种情况下,我认为您最好为 Product
标签设置一个处理程序,您可以在其中获取 id 数据,然后更新两个子元素.
There are 2 problems in your initial code: first I don't think get
is an XML::Twig::Elt method. Then you first prefix the ExternalId
text, then (once prefixed) try to use it to update ProductPageUrl
. That won't work. In this case I think you're better off having a single handler, for the Product
tag, in which you get the id data, then update both sub-elements.
这里有一个解决方案,作为测试编写,以便在您的输出发生变化时更容易更新:
Here a solution, written as a test so it's easier to update if your output changes:
#!/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>
这篇关于使用 XML::Twig 复制 XML 值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!