Given the below XML and script, I can produce this:
{
Item => {
Details => { color => { Val => "green" }, texture => { Val => "smooth" } },
},
}
but, I really want the following:
{
Item => {
Details => { color => "green", texture => "smooth" },
},
}
I can't use GroupTags here because there could be many Details items (Key/Val pairs), and they could be unknown before processing. Is it possible to produce the desired structure with开发者_运维百科out resorting to manual extraction via XPath, SAX, etc.?
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>
Add a ContentKey
parameter:
my $obj = XMLin(
$xml,
NoAttr => 1,
GroupTags => { Details => 'Item' },
KeyAttr => [ 'Key'],
ContentKey => '-Val',
);
Output:
{ Item => { Details => { color => "green", texture => "smooth" } }, }
The docs explain:
ContentKey => 'keyname'
# in+out - seldom usedWhen text content is parsed to a hash value, this option lets you specify a name for the hash key to override the default
'content'
. So for example:XMLin('<opt one="1">Text</opt>', ContentKey => 'text')
will parse to:
{ 'one' => 1, 'text' => 'Text' }
instead of:
{ 'one' => 1, 'content' => 'Text' }
XMLout
will also honour the value of this option when converting a hashref to XML.You can also prefix your selected key name with a
'-'
character to haveXMLin
try a little harder to eliminate unnecessary'content'
keys after array folding.
精彩评论