【发布时间】:2012-12-12 11:54:04
【问题描述】:
我正在使用XML::Twig 解析一个非常大的 XML 文档。我想根据<change></change> 标签把它分成块。
现在我有:
my $xml = XML::Twig->new(twig_handlers => { 'change' => \&parseChange, });
$xml->parsefile($LOGFILE);
sub parseChange {
my ($xml, $change) = @_;
my $message = $change->first_child('message');
my @lines = $message->children_text('line');
foreach (@lines) {
if ($_ =~ /[^a-zA-Z0-9](?i)bug(?-i)[^a-zA-Z0-9]/) {
print outputData "$_\n";
}
}
outputData->flush();
$change->purge;
}
现在,当它从 XML 中提取该块时,它正在运行 parseChange 方法。它进展非常缓慢。我测试了它是否可以从带有$/=</change> 的文件中读取 XML 并编写一个函数来返回 XML 标记的内容,并且速度要快得多。
是我遗漏了什么还是我错误地使用了XML::Twig?我是 Perl 新手。
编辑:这是更改文件的示例更改。该文件由很多这样一个接一个地组成,它们之间不应该有任何东西:
<change>
<project>device_common</project>
<commit_hash>523e077fb8fe899680c33539155d935e0624e40a</commit_hash>
<tree_hash>598e7a1bd070f33b1f1f8c926047edde055094cf</tree_hash>
<parent_hashes>71b1f9be815b72f925e66e866cb7afe9c5cd3239</parent_hashes>
<author_name>Jean-Baptiste Queru</author_name>
<author_e-mail>jbq@google.com</author_e-mail>
<author_date>Fri Apr 22 08:32:04 2011 -0700</author_date>
<commiter_name>Jean-Baptiste Queru</commiter_name>
<commiter_email>jbq@google.com</commiter_email>
<committer_date>Fri Apr 22 08:32:04 2011 -0700</committer_date>
<subject>chmod the output scripts</subject>
<message>
<line>Change-Id: Iae22c67066ba4160071aa2b30a5a1052b00a9d7f</line>
</message>
<target>
<line>generate-blob-scripts.sh</line>
</target>
</change>
【问题讨论】:
-
我认为在将 XML 传递给
XML::Twig之前使用正则表达式对其进行预处理不是一个好主意。它使您的代码变得不那么健壮。例如,如果评论中有</change>怎么办?此外,XML 解析不太可能会减慢您的脚本速度。您能否提供更多信息:文件的大小以及您正在进行什么样的处理? -
我现在没有在任何地方使用正则表达式。一种方法是使用 twig,另一种方法是读入并自己解析。我从整个脚本中提取了这一部分,所以它是唯一正在运行的东西。此外,文件大小为 2.3gb。我正在从 xml 中提取数据并将其中的一些添加到哈希中。
-
抱歉,说“正则表达式”是个错误。我的意思是,如果您在解析文件之前使用某些规则(例如行分隔符)分解文件,则可能会破坏 XML 的完整性。你的 XML 文件有多大?
-
文件为 2.3gb。它是来自 git 存储库的 xml 格式的更改日志
-
更多信息:它在那里解析了至少一个小时,而使用行分隔符的解析器花了大约 15-20 分钟来做同样的事情。
标签: xml perl parsing large-files xml-twig