我使用XML::Twig处理程序/根从大型XML文件中提取信息,在这些文件中,将整个文件加载到内存中成本过高。这些XML文件是Excel文件的内部工作表文件。
到目前为止,这种方法一直行之有效。下面是从内部XML文件sheet1.xml提取所有单元格引用的示例。
use strict;
use warnings;
use Archive::Zip qw(:ERROR_CODES :CONSTANTS);
use XML::Twig;
use Data::Dumper;
my $zipName='TestFile.xlsx';
my $zip = Archive::Zip->new();
my $zipread;
$zipread=$zip->read($zipName);
my $tw1=new XML::Twig();
my $fileToAnalyse='xl/worksheets/sheet1.xml';
my $sheetFile = $zip->contents($fileToAnalyse);
my @Results;
my $t= XML::Twig->new(twig_roots => {'worksheet/sheetData/row/c' =>
sub { Get_Sheet_Data_TEST_1(@_,\@Results);}})->parse($sheetFile);
print Dumper \@Results;
sub Get_Sheet_Data_TEST_1{
my($t,$elt,$Results)= @_;
my @attrib_NAMES=$elt->att_names();
for my $attrib_loop (0 .. scalar @attrib_NAMES-1){
if($attrib_NAMES[$attrib_loop] eq 'r'){
push @$Results,$elt->att($attrib_NAMES[$attrib_loop]);
}
}
$t->purge; # frees the memory
}有时,这些文件有我要找的标记的前缀。
所以
'worksheet/sheetData/row/c'变成了
'x:worksheet/x:sheetData/x:row/x:c'现在,我的处理程序从不触发,因为它找不到所需的标记。
有没有任何方法可以修改我的处理程序,而不需要硬编码所有可能的前缀,这样就可以匹配这些前缀以及没有前缀的“通常”标记?
也许有一种方法可以找到任何给定文件预先使用的前缀,并将这些值设置为一个变量,然后将其传递给我的处理程序。
发布于 2022-01-20 08:08:26
好吧,我找到了解决办法。原来XML::Twig有一个可选的参数
map_xmlns我可以用这个解决我的问题。所以,我的原始代码
my $t= XML::Twig->new(twig_roots => {'worksheet/sheetData/row/c' =>
sub { Get_Sheet_Data_TEST_1(@_,\@Results);}})->parse($sheetFile);变成了
my $t= XML::Twig->new(
map_xmlns => {
'http://schemas.openxmlformats.org/spreadsheetml/2006/main' => 's'},
twig_roots => {'s:worksheet/s:sheetData/s:row/s:c' =>
sub { Get_Sheet_Data_TEST_1(@_,\@Results);}})->parse($sheetFile);现在,我的处理程序适用于所有前缀(甚至是空前缀!)。
如XML::Twig文档中所写:
map_xmlns
此选项被传递给hashref,该hashref将uri映射为前缀。文档中的前缀将被地图中的前缀替换。映射的前缀可以(实际上必须)用于触发处理程序、导航或查询文档。
https://stackoverflow.com/questions/70768887
复制相似问题