Perl,使用XML解析XML ::简单且有问题

时间:2012-01-17 01:08:28

标签: arrays perl hash xml-parsing xml-simple

我正在解析Perl中的xml文件,一切似乎都很好用一个问题。我有相同模式的文件,但它们从解析器返回不同类型的数据。这是一个简化的例子:

<tests>
       <test>
          <data1>Hi</data1>
          <data2>Hello</data2>
       </test>
       <test>
          <data1>Hi2</data1>
          <data2>Hello2</data2>
       </test>
  </tests>

在转储中,返回以下内容:(注意test是两个哈希的数组)

$VAR1 = {
          'test' => [
                    {
                      'data2' => 'Hello',
                      'data1' => 'Hi'
                    },
                    {
                      'data2' => 'Hello2',
                      'data1' => 'Hi2'
                    }
                  ]
        };

现在,对于一组类似的数据,但只有一个“测试”实体如此:

  <tests>
       <test>
          <data1>Hi</data1>
          <data2>Hello</data2>
       </test>
  </tests>

这会返回类似的数据,EXCEPT测试实体不再是数组,而是一个单数哈希:

$VAR1 = {
          'test' => {
                    'data2' => 'Hello',
                    'data1' => 'Hi'
                  }
        };

我的困境是我的代码需要一个数组,因为这是常态。但是,当只有一个实体的机会很小时,它将返回该实体的哈希值。我的问题是,我如何处理哈希实体,就好像它是一个数组。或者测试一下?

现在我检索数组的代码是这样的:

foreach $test (@{$data->{'tests'}->{'test'}})
{
   do something with $test
}

但是使用哈希,它会给出错误“Not a ARRAY reference”。我希望这是足够的细节!感谢!!!

4 个答案:

答案 0 :(得分:6)

也许ForceArray选项的替代形式是您想要的?

  

ForceArray =&gt; [姓名]

     

'ForceArray'选项的替代(和首选)形式   允许您指定应始终为的元素名称列表   强制进入数组表示,而不是“全有或全无”   接近上面。

     

也可以(从版本2.05开始)包含已编译的常规   列表中的表达式 - 与模式匹配的任何元素名称   将被迫阵列。如果列表只包含一个正则表达式,   那么没有必要将它包含在arrayref中。例如:

     

ForceArray =&gt; QR / _list $ /

所以我可能会尝试:

ForceArray => ['test']

答案 1 :(得分:1)

XML::Simple

ForceArray => 1
  

此选项应设置为“1”以强制嵌套元素   即使只有一个

,也表示为数组

答案 2 :(得分:0)

您需要使用散列符号取消引用哈希:'%'。

答案 3 :(得分:0)

虽然看起来您可以让XML解析器的行为更加一致,但是使代码在变量输出上工作也不难。

Perl内置函数“ref”可用于确定引用所引用的对象类型。

原始代码

foreach $test (@{$data->{'tests'}->{'test'}})
{
    do something with $test
}

(而不是写$ data-&gt; {'tests'} - &gt; {'test'},我倾向于使用更紧凑的$$数据{tests} {test},所以我会使用它在我的例子中。)

我们可以检查引用类型并使用它来将所有可能性推送到数组中,所以

foreach $test (
    (ref($$data{tests}{test}) eq 'ARRAY') ? (
        @{$$data{tests}{test}}
    ) : (
        $$data{tests}{test}
    )
)
{
    do something with $test
}