是否有可能从XML :: Simple进一步简化结果数据结构?

时间:2010-06-29 00:43:15

标签: xml perl

鉴于以下XML和脚本,我可以产生这个:

{
  Item => {
    Details => { color => { Val => "green" }, texture => { Val => "smooth" } },
  },
}

但是,我真的想要以下内容:

{
  Item => {
    Details => { color => "green", texture => "smooth" },
  },
}

我不能在这里使用GroupTags,因为可能有许多详细信息项(Key / Val对),并且在处理之前它们可能是未知的。是否有可能在不通过XPath,SAX等手动提取的情况下生成所需的结构?

use strict;
use warnings;
use Data::Dump;
use XML::Simple;


my $xml = do { local $/; scalar <DATA> };
my $obj = XMLin(
    $xml,
    NoAttr     => 1,
    GroupTags  => { Details => 'Item' },
    KeyAttr => [ 'Key'],
);
dd($obj);
exit;

__END__
<?xml version="1.0" encoding="UTF-8"?>
<List attr="ignore">
    <Item attr="ignore">
        <Details attr="ignore">
            <Item attr="ignore">
                <Key>color</Key>
                <Val>green</Val>
            </Item>
            <Item attr="ignore">
                <Key>texture</Key>
                <Val>smooth</Val>
            </Item>
        </Details>
    </Item>
</List>

1 个答案:

答案 0 :(得分:5)

添加ContentKey参数:

my $obj = XMLin(
    $xml,
    NoAttr     => 1,
    GroupTags  => { Details => 'Item' },
    KeyAttr    => [ 'Key'],
    ContentKey => '-Val',
);

输出:

{
  Item => { Details => { color => "green", texture => "smooth" } },
}

文档说明:

  

ContentKey => 'keyname'#in + out - 很少使用

     

当文本内容被解析为哈希值时,此选项允许您指定哈希键的名称以覆盖默认的'content'。例如:

XMLin('<opt one="1">Text</opt>', ContentKey => 'text')
     

将解析为:

{ 'one' => 1, 'text' => 'Text' }
     

而不是:

{ 'one' => 1, 'content' => 'Text' }
     将hashref转换为XML时,

XMLout也会尊重此选项的值。

     

您还可以使用'-'字符为所选键名添加前缀,让XMLin稍微努力一点,以便在数组折叠后消除不必要的'content'键。