我有一个大的(> 2gb)XML文件,看起来大致如下:
<record id="1">
<a>
<detail>blah</detail>
....
<detail>blah</detail>
</a>
<b>
<detail>blah</detail>
....
<detail>blah</detail>
</b>
<c>
<detail>blah</detail>
....
<detail>blah</detail>
</c>
</record>
...
<record id="999999">
<a>
<detail>blah</detail>
....
<detail>blah</detail>
</a>
<b>
<detail>blah</detail>
....
<detail>blah</detail>
</b>
<c>
<detail>blah</detail>
....
<detail>blah</detail>
</c>
</record>
Run Code Online (Sandbox Code Playgroud)
但是,我的实际文件没有每个节点的换行符(尽管在整个过程中随机散布了一些换行符.)
我想使用Perl删除每个节点<b>中的所有 <record>节点,包括它们的后代.
所以 - 我的结果文件看起来像这样:
<record id="1">
<a>
<detail>blah</detail>
....
<detail>blah</detail>
</a>
<c>
<detail>blah</detail>
....
<detail>blah</detail>
</c>
</record>
...
<record id="999999">
<a>
<detail>blah</detail>
....
<detail>blah</detail>
</a>
<c>
<detail>blah</detail>
....
<detail>blah</detail>
</c>
</record>
Run Code Online (Sandbox Code Playgroud)
这是一个重要的注释......正如我所提到的,文件大约是2.4gb.对于较小的文件,我使用XMLReader和PHP来成功解析文件并提取我需要的内容.但是,似乎PHP无法处理这么大的文件(PHP <v.5.6使用32位文件指针).因此,我的目标是使用类似的实用程序sed或perl通过剥离我不需要的大块来减少文件.我知道"XML-aware"实用程序更适合这种类型的工作,但我还没有找到一个可以处理这么大的文件...
无论如何,我试过这个(@用作我的分隔符):
perl -pe 's@<b>.*</b>@@sg' input.xml > modified.xml
Run Code Online (Sandbox Code Playgroud)
但这没有用 - 它根本没有删除任何节点.
我确信<b>节点没有任何会破坏模式的属性.
显然 - 我说到这是一个菜鸟,所以我相信我甚至不会接近......
XML :: Twig可用于从大型XML文件中剪切元素,而不必担心元素之间的空白:
use warnings;
use strict;
use XML::Twig;
my $xml = do { local $/; <DATA> };
my $twig = XML::Twig->new(
twig_handlers => {
'record/b' => sub { $_->cut() }
},
pretty_print => 'indented'
);
$twig->parse($xml);
$twig->print();
__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<top>
<record id="1">
<a>
<detail>blah</detail>
<detail>blah</detail>
</a>
<b>
<detail>blah</detail>
<detail>blah</detail>
</b>
<c>
<detail>blah</detail>
<detail>blah</detail>
</c>
</record>
<record id="999999">
<a>
<detail>blah</detail>
<detail>blah</detail>
</a>
<b>
<detail>blah</detail>
<detail>blah</detail>
</b>
<c>
<detail>blah</detail>
<detail>blah</detail>
</c>
</record>
</top>
Run Code Online (Sandbox Code Playgroud)
这是输出:
<?xml version="1.0" encoding="UTF-8"?>
<top>
<record id="1">
<a>
<detail>blah</detail>
<detail>blah</detail>
</a>
<c>
<detail>blah</detail>
<detail>blah</detail>
</c>
</record>
<record id="999999">
<a>
<detail>blah</detail>
<detail>blah</detail>
</a>
<c>
<detail>blah</detail>
<detail>blah</detail>
</c>
</record>
</top>
Run Code Online (Sandbox Code Playgroud)