读取文件的xml行并复制到Perl中的数组?

时间:2015-08-06 06:59:30

标签: xml perl

我有一个名为test.xml的文件,如下所示:

<temp id="abc1">32769</temp><temp id="abc2">0</temp><temp id="abc3">N</temp><temp id="abc4">1</temp>
<test id="abc5">D</test><test id="abc6">NS</test><test id="abc7">NG</test>

我想在</temp>,</test>之后引入换行符,然后将每行复制到数组(比如@array),如下所示:

$array[1]=<temp id="abc1">32769</temp>
$array[2]=<temp id="abc2">0</temp>
$array[3]=<temp id="abc3">N</temp>
$array[4]=<temp id="abc4">1</temp>
$array[5]=<test id="abc5">D</test>
$array[6]=<test id="abc6">NS</test>
$array[7]=<test id="abc7">NG</test>

我尝试过使用foreach循环

open (INPUT, "$test file"); 
foreach (<INPUT>) { 
   s/\<\/test\>/\<\/test\>\n/g;
   s/\<\/temp\>/\<\/temp\>\n/g; 
} 
my array = <INPUT>;

3 个答案:

答案 0 :(得分:1)

使用此正则表达式获取您的数据,即延迟匹配您的数据,直至/,然后再懒洋洋地匹配到>。:

将结果放入@array

#!/usr/bin/perl
use Data::Dumper;
use strict;
use warnings;

my $string='<temp id="abc1">32769</temp><temp id="abc2">0</temp><temp id="abc3">N</temp><temp id="abc4">1</temp>
<test id="abc5">D</test><test id="abc6">NS</test><test id="abc7">NG</test>';

my @array=$string=~/(<.+?(?=[\/]).+?(?=[>])>)/g;

print Dumper(\@array);

<强>输出:

[
  '<temp id="abc1">32769</temp>',
  '<temp id="abc2">0</temp>',
  '<temp id="abc3">N</temp>',
  '<temp id="abc4">1</temp>',
  '<test id="abc5">D</test>',
  '<test id="abc6">NS</test>',
  '<test id="abc7">NG</test>'
 ];

答案 1 :(得分:1)

使用正则表达式解析XML是个坏主意。这是一个非常糟糕的主意,因为它在短期内会起作用,但有一天会破碎,没有人会真正知道原因。

请不要这样做 - 您未来的系统管理员和维护程序员会很伤心。

请请使用XML解析器。有几个存在。 (只是不是XML::Simple,这就是说简单)。

但我也会质疑为什么你需要在数组中拥有这样的元素呢?你在用什么信息?如果要重建一些XML ...不要。只需使用解析器即可。

否则:

#!/usr/bin/env perl
use strict;
use warnings;
use Data::Dumper;

use XML::Twig;

my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' );
$twig->parse( \*DATA );

#print reformatted XML
$twig->print;

my @things;

#extract elements
foreach my $element ( $twig->root->children ) {

    #insert into array.
    push( @things, $element->sprint );
}

print Dumper \@things;

__DATA__
<root>
<temp id="abc1">32769</temp><temp id="abc2">0</temp><temp id="abc3">N</temp><temp id="abc4">1</temp>
<test id="abc5">D</test><test id="abc6">NS</test><test id="abc7">NG</test>
</root>

但是,您可以做一些其他更有用的事情,数据结构明智。喜欢转换为哈希,这可能更有用

e.g:

my %stuff;

#extract elements
foreach my $element ( $twig->root->children ) {
   my $tag = $element -> tag;
   my $id = $element -> att('id'); 
   $stuff{$tag}{$id} = $element -> trimmed_text; 
}

print Dumper \%stuff;

创建一个类似于:

的数据结构
$VAR1 = {
          'test' => {
                    'abc5' => 'D',
                    'abc6' => 'NS',
                    'abc7' => 'NG'
                  },
          'temp' => {
                    'abc1' => '32769',
                    'abc4' => '1',
                    'abc2' => '0',
                    'abc3' => 'N'
                  }
        };

为什么使用正则表达式进行XML解析是不好的?每个都是语义相同的XML。处理它的正则表达式变得非常复杂和痛苦,因为您需要处理标记嵌套和封装。

<root>
<temp id="abc1">32769</temp><temp id="abc2">0</temp><temp id="abc3">N</temp><temp id="abc4">1</temp>
<test id="abc5">D</test><test id="abc6">NS</test><test id="abc7">NG</test>
</root>

<root>
  <temp id="abc1">32769</temp>
  <temp id="abc2">0</temp>
  <temp id="abc3">N</temp>
  <temp id="abc4">1</temp>
  <test id="abc5">D</test>
  <test id="abc6">NS</test>
  <test id="abc7">NG</test>
</root>

<root
><temp
id="abc1"
>32769</temp><temp
id="abc2"
>0</temp><temp
id="abc3"
>N</temp><temp
id="abc4"
>1</temp><test
id="abc5"
>D</test><test
id="abc6"
>NS</test><test
id="abc7"
>NG</test></root>

<root><temp id="abc1">32769</temp><temp id="abc2">0</temp><temp id="abc3">N</temp><temp id="abc4">1</temp><test id="abc5">D</test><test id="abc6">NS</test><test id="abc7">NG</test></root>

答案 2 :(得分:0)

为什么不试试以下内容?

open(DATA, "<pqr.xml") or die "Couldn't open file pqr.xml, $!";
my $y='';
while(<DATA>){
    $_=~s/(<\/temp>)/$1\n/g;
    $_=~s/(<\/test>)/$1\n/g;
    $_=~s/(\n)+/\n/g;
    print $_;
    $y.=$_;
}
my @x=split(/\n/,$y);