我正在解析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”。我希望这是足够的细节!感谢!!!
答案 0 :(得分:6)
也许ForceArray
选项的替代形式是您想要的?
ForceArray =&gt; [姓名]
'ForceArray'选项的替代(和首选)形式 允许您指定应始终为的元素名称列表 强制进入数组表示,而不是“全有或全无” 接近上面。
也可以(从版本2.05开始)包含已编译的常规 列表中的表达式 - 与模式匹配的任何元素名称 将被迫阵列。如果列表只包含一个正则表达式, 那么没有必要将它包含在arrayref中。例如:
ForceArray =&gt; QR / _list $ /
所以我可能会尝试:
ForceArray => ['test']
答案 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
}