想要根据标签拆分 UNIX xml 文件
Want to split an UNIX xml file based on tags
我有一个 XML 文件,其中包含如下批次。
我想使用 shell 脚本根据标签将此文件拆分为 5 个文件。
请帮助,提前致谢。
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
</Items>
期望的输出:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
</Items>
我建议 - 安装 XML::Twig
which includes the rather handy xml_split
实用程序。那可能会做你需要的。例如:
xml_split -c Item
不过,我想说的是您要完成的事情并不容易,因为您要拆分并保留 XML 结构。您无法使用基于 line/regex 的标准工具来完成。
但是您可以使用解析器:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my @item_list;
sub cut_item {
my ( $twig, $item ) = @_;
my $thing = $item->cut;
push( @item_list, $thing );
}
my $twig = XML::Twig->new(
twig_handlers => { 'Item' => \&cut_item }
);
$twig->parse(<>);
my $itemcount = 1;
foreach my $element (@item_list) {
my $newdoc = XML::Twig->new( 'pretty_print' => 'indented_a' );
$newdoc->set_root( XML::Twig::Elt->new('Items') );
$element->paste( $newdoc->root );
$newdoc->print;
open( my $output, ">", "items_" . $itemcount++ . ".xml" );
print {$output} $newdoc->sprint;
close($output);
}
这使用 XML::Twig
库从您的 XML 中提取每个 Item
元素(在 STDIN 上传输,或通过 myscript.pl yourfilename
)。
然后迭代所有它找到的,添加一个 Items
header,并将其打印到一个单独的文件中。如果你有一个更复杂的根,这种方法可能会更麻烦一点,但如果你这样做的话,它是可以适应的。
我有一个 XML 文件,其中包含如下批次。
我想使用 shell 脚本根据标签将此文件拆分为 5 个文件。 请帮助,提前致谢。
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
<Item>
<Title>Title 2</Title>
<DueDate>01-02-2009</DueDate>
</Item>
<Item>
<Title>Title 3</Title>
<DueDate>01-02-2010</DueDate>
</Item>
<Item>
<Title>Title 4</Title>
<DueDate>01-02-2011</DueDate>
</Item>
<Item>
<Title>Title 5</Title>
<DueDate>01-02-2012</DueDate>
</Item>
</Items>
期望的输出:
<Items>
<Item>
<Title>Title 1</Title>
<DueDate>01-02-2008</DueDate>
</Item>
</Items>
我建议 - 安装 XML::Twig
which includes the rather handy xml_split
实用程序。那可能会做你需要的。例如:
xml_split -c Item
不过,我想说的是您要完成的事情并不容易,因为您要拆分并保留 XML 结构。您无法使用基于 line/regex 的标准工具来完成。
但是您可以使用解析器:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my @item_list;
sub cut_item {
my ( $twig, $item ) = @_;
my $thing = $item->cut;
push( @item_list, $thing );
}
my $twig = XML::Twig->new(
twig_handlers => { 'Item' => \&cut_item }
);
$twig->parse(<>);
my $itemcount = 1;
foreach my $element (@item_list) {
my $newdoc = XML::Twig->new( 'pretty_print' => 'indented_a' );
$newdoc->set_root( XML::Twig::Elt->new('Items') );
$element->paste( $newdoc->root );
$newdoc->print;
open( my $output, ">", "items_" . $itemcount++ . ".xml" );
print {$output} $newdoc->sprint;
close($output);
}
这使用 XML::Twig
库从您的 XML 中提取每个 Item
元素(在 STDIN 上传输,或通过 myscript.pl yourfilename
)。
然后迭代所有它找到的,添加一个 Items
header,并将其打印到一个单独的文件中。如果你有一个更复杂的根,这种方法可能会更麻烦一点,但如果你这样做的话,它是可以适应的。