我在目录中有许多XML文件需要排序并合并到一个文件中。文件格式如下:
File1.xml:
<?xml version="1.0" encoding="utf-8"?>
<doctypea>
<header someattr="1">
<docnumber>111</docnumber>
</header>
</doctypea>
File2.xml:
<?xml version="1.0" encoding="utf-8"?>
<doctypea>
<header someattr="1">
<docnumber>112</docnumber>
</header>
</doctypea>
File3.xml:
<?xml version="1.0" encoding="utf-8"?>
<doctypeb>
<header someattr="1">
<docnumber>111</docnumber>
</header>
</doctypeb>
File4.xml:
<?xml version="1.0" encoding="utf-8"?>
<doctypeb>
<header someattr="1">
<docnumber>112</docnumber>
</header>
</doctypeb>
此目录中的所有文件都需要按以下标准排序:
然后需要合并它们,因此输出文件应如下所示:
<?xml version="1.0" encoding="utf-8"?>
<doctypea>
<header someattr="1">
<docnumber>111</docnumber>
</header>
</doctypea>
<doctypeb>
<header someattr="1">
<docnumber>111</docnumber>
</header>
</doctypeb>
<doctypea>
<header someattr="1">
<docnumber>112</docnumber>
</header>
</doctypea>
<doctypeb>
<header someattr="1">
<docnumber>112</docnumber>
</header>
</doctypeb>
为了实现这一点,我尝试使用XML:Perl中的Twig。到目前为止,我有以下代码:
use XML::Twig;
my $xmldir = "/xmlfiles";
my $parser = XML::Twig->new(pretty_print => 'indented');
opendir(DIR, "$xmldir");
my @FILES= readdir(DIR);
closedir(DIR);
foreach (@FILES) {
if ($_ ne "." && $_ ne "..") {
print "reading file: $xmldir/$_\n";
$parser->parsefile("$xmldir/$_");
}
}
此时我似乎无法找出正确的语法来从解析器中获取我想要的元素。
1。如何获取根元素的值(&#34; doctypea&#34;或&#34; doctypeb&#34;)?
2。我假设我需要(1)才能将语法编码下载到docnumber字段?
我的计划是使用doctype%number构建某种类型以进行排序,我不确定将它们与之合并的最简单方法。
感谢任何建议!
答案 0 :(得分:5)
请在下面找到应该让您入门的小例子。它显示了如何从XML文件中获取与您类似的数据(我修复了标记以匹配并引用someattr
值以获取有效的XML)。您可以使用类似的方法收集所需的数据并生成输出。
use XML::Twig;
XML::Twig->new(twig_handlers => {
'/*' => sub { print $_->gi; }, # doctypea
'docnumber' => sub { print $_->trimmed_text; }, # 111
})->parse(\*DATA); # use parsefile('xxx.xml') to parse a file
__DATA__
<?xml version="1.0" encoding="utf-8"?>
<doctypea>
<header someattr="1">
<docnumber>111</docnumber>
</header>
</doctypea>
答案 1 :(得分:1)
正如daxim所注意到的,您的文件不是有效的XML,但您可以使用正则表达式处理它们。如果文件不是太大,您可以将文件粘贴到您根据其内容排序的单个字符串中。
use File::Slurp qw( read_dir ) ;
my $xmldir=".";
my %files = map {
s/^.*$//m;
/<doctype([ab])>/; my $x=ord($1) - ord('a');
/<docnumber>(\d+)</docnumber>/; $x += 10*$2;
$x => $_
} read_dir($xmldir);
print join("", map { $files{$_} } sort keys %files);
我没有调试此代码。 print join("", values %files);
也可能有用。