使用 perl 替换文件夹中多个 XML 文件的值 [英] Replace values for multiple XML files in a folder using perl

查看:52
本文介绍了使用 perl 替换文件夹中多个 XML 文件的值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在文件夹 "c:\srini\perl\in\" 中有多个 XML 文件......所有这些文件的结构都是相同的......我需要在每个 XML 中搜索两个标签,如果是TAG 值中包含@@@"...它必须替换为&"...它必须检查两个标签值 SHORT_DESC 和 XXX_NAME ...如果任何 TAG 值中包含@@@"..它必须被替换为&"..下面是 XML 文件....

I have multiple XML files in a folder "c:\srini\perl\in\" ... the structure of all these files are the same ... I need to search for two tags in each XML and if that TAG values has "@@@" in it ...it has to be replaced with "&" ... it has to check for two tag values SHORT_DESC and XXX_NAME ...if any of the TAG value has "@@@" in it ..it has to be replaced with "&".. Below is the XML file ....

<TOPHEADER>
<HEADER>
<NAME>ABC LTD</NAME>
<SHORT_DESC>ABC COMPY @@@ LTD</SHORT_DESC> 
<XXX_NAME>ABC COMPANY FOR XXX AND YYY </XXX_NAME> 
</HEADER>
<HEADER>
<NAME>XYZ LTD</NAME>
<SHORT_DESC>XYZ COMPY @@@ LTD</SHORT_DESC> 
<XXX_NAME>XYZ COMPANY FOR @@@</XXX_NAME> 
</HEADER>
<HEADER>
<NAME>DEF LTD</NAME>
<SHORT_DESC>DEF COMPY AND LTD</SHORT_DESC> 
<XXX_NAME>DEF COMPANY FOR @@@</XXX_NAME> 
</HEADER>
</TOPHEADER>

我正在使用下面的代码来替换单个文件的标签值......但想知道是否有更好的方法来处理多个文件......

I'm using the below code to replace the tag value for a single file .. but wanted to know if there is a better way to handle multiple files ....

open (my $input_file, '<', 'c:\srini\perl\in\test1.xml') or die "unable to open $input_file $!\n";
open (my $output_file, '>', 'c:\srini\perl\in\test1_out.xml') or die "unable to open $output_file $!\n";

my $input;
{
local $/;               #Set record separator to undefined.
$input = <$input_file>; #This allows the whole input file to be read at once.
}
$input =~ s/@@@/&/g;

print {$output_file} $input;

close $input_file or die $!;
close $output_file or die $!;

推荐答案

您意识到您的输出将不是有效的 XML,对吗?&需要在 XML 中转义.希望这只是一个例子,而不是真正的价值.

You realize that your output will not be valid XML right? The & needs to be escaped in XML. Hopefully it was just an example and not the real value.

也就是说,我想使用XML 方式"™,例如使用 XML::Twig,这非常简单:

That said, I you want to do this "The XML way"™, for example using XML::Twig, that's pretty simple:

#!/usr/bin/perl

use strict;
use warnings;

use XML::Twig;

my $dir= shift @ARGV or die "usege: $0 <dir>\n";

foreach my $file ( glob( "$dir/*.xml"))
  { XML::Twig->new( twig_roots => { SHORT_DESC => \&replace, # only those elements will be checked
                                    XXX_NAME   => \&replace,
                                  },
                    twig_print_outside_roots => 1,           # the rest will be output as-is
                    keep_spaces => 1,
                  )
             ->parsefile_inplace( $file);                    # the original file will be updated
  }

exit;

sub replace
  { my( $t, $elt)= @_;
    $elt->subs_text( qr/@@@/, '&')->print;
  }

输出将是格式良好的 XML(即 它看起来像 <SHORT_DESC>ABC COMPY & LTD</SHORT_DESC>).如果您确实需要 &为了不被转义,sub 中的行应该是 $elt->subs_text( qr/@@@/, '&')->set_asis(1)->print;,对 set_asis 的调用会阻止元素的文本被转义.

The output will be well-formed XML (ie it will look like <SHORT_DESC>ABC COMPY &amp; LTD</SHORT_DESC>). If you do need the & not to be escaped, the line in the sub should be $elt->subs_text( qr/@@@/, '&')->set_asis( 1)->print;, the call to set_asis prevents the text of the element to be escaped.

请确保您的原始 XML 格式正确,否则它不会被处理(尽管您不会丢失数据).

Make sure your original XML is well-formed though, or it will not be processed (you won't lose the data though).

这篇关于使用 perl 替换文件夹中多个 XML 文件的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆