XML::Simple folding broken for single items?

  • Thread starter it_says_BALLS_on_your_forehead
  • Start date
I

it_says_BALLS_on_your_forehead

To: Grant McLean

am i missing something? it appears that "folding" is broken for single
items. this is for ver. 2.14.
i'm basing subroutine on the data structure created by XMLin(), but it
assumes that folding will occur even on single elements. did i miss
something in the docs? i just would like to know oif this is working as
it should, and i need to code around it, or if this is a bug. try the
code below with $good versus $bad, and you will see what i mean. the
$good string is the same as in the docs. thanks! LOVE the module btw
:-D.

==================
use strict; use warnings;

use XML::Simple;
use Data::Dumper;

my $good = q{<opt><user login="grep" fullname="Gary R Epstein" />} .
q{<user login="stty" fullname="Simon T Tyson" /></opt>};
my $bad = q{<opt><user login="grep" fullname="Gary R Epstein" />} .
q{</opt>};

my $ref = XMLin($bad,
#ForceArray => 1,
KeyAttr => ['login'],
GroupTags => {data => 'item'},
);

print Dumper($ref);

=====

$VAR1 = {
'user' => {
'fullname' => 'Gary R Epstein',
'login' => 'grep'
}
};
 
M

Matt Garrish

it_says_BALLS_on_your_forehead said:
To: Grant McLean

am i missing something? it appears that "folding" is broken for single
items. this is for ver. 2.14.
i'm basing subroutine on the data structure created by XMLin(), but it
assumes that folding will occur even on single elements. did i miss
something in the docs? i just would like to know oif this is working as
it should, and i need to code around it, or if this is a bug. try the
code below with $good versus $bad, and you will see what i mean. the
$good string is the same as in the docs. thanks! LOVE the module btw
:-D.

==================
use strict; use warnings;

use XML::Simple;
use Data::Dumper;

my $good = q{<opt><user login="grep" fullname="Gary R Epstein" />} .
q{<user login="stty" fullname="Simon T Tyson" /></opt>};
my $bad = q{<opt><user login="grep" fullname="Gary R Epstein" />} .
q{</opt>};

my $ref = XMLin($bad,
#ForceArray => 1,

Why did you comment out that line? As per the documnetation for KeyAttr:

<quote>
Note 2: If you wish to use this option, you should also enable the
ForceArray option. Without 'ForceArray', a single nested element will be
rolled up into a scalar rather than an array and therefore will not be
folded (since only arrays get folded).
</quote>

Setting ForceArray gives me exactly the same result as when there are two+
elements, so I don't see any bug here.

Matt
 
I

it_says_BALLS_on_your_forehead

Matt said:
Why did you comment out that line? As per the documnetation for KeyAttr:

<quote>
Note 2: If you wish to use this option, you should also enable the
ForceArray option. Without 'ForceArray', a single nested element will be
rolled up into a scalar rather than an array and therefore will not be
folded (since only arrays get folded).
</quote>

Setting ForceArray gives me exactly the same result as when there are two+
elements, so I don't see any bug here.


ahh, i missed that in the docs (going blind). i did notice that it
worked if i turned ForceArray on, but I thought it should do it if
ForceArray was off as well. The reason i turned it off was because it
seemed to disable GroupTag (or maybe i just missed something else in
the documentation, although i looked).

====
use strict; use warnings;

use XML::Simple;
use Data::Dumper;
$XML::Simple::pREFERRED_PARSER = 'XML::parser';

my $line = q{<application_log name="BranchFinder"><event t="123">} .
q{<data><item><name>zip</name><value>02109</value></item>} .
q{<item><name>method</name><value>Get</value></item>} .
q{<item><name>zip2</name><value>22222</value></item>} .
q{</data></event></application_log>};


# GroupTags eliminates extra level of indirection
# <data> must not contain attributes or non-<item> elements
my $ref = XMLin($line,
ForceArray => 1,
#KeyAttr => ['name'],
GroupTags => {data => 'item'},
);

print Dumper($ref);

__END__

$VAR1 = {
'name' => 'BranchFinder',
'event' => [
{
'data' => [
{
'item' => [
{
'value' => [
'02109'
],
'name' => [
'zip'
]
},
{
'value' => [
'Get'
],
'name' => [
'method'
]
},
{
'value' => [
'22222'
],
'name' => [
'zip2'
]
}
]
}
],
't' => '123'
}
]
};

======
whereas if i turn off ForceArray, GroupTag works...
$VAR1 = {
'name' => 'BranchFinder',
'event' => {
'data' => {
'zip' => {
'value' => '02109'
},
'zip2' => {
'value' => '22222'
},
'method' => {
'value' => 'Get'
}
},
't' => '123'
}
};
 
I

it_says_BALLS_on_your_forehead

it_says_BALLS_on_your_forehead said:
Matt said:
Why did you comment out that line? As per the documnetation for KeyAttr:

<quote>
Note 2: If you wish to use this option, you should also enable the
ForceArray option. Without 'ForceArray', a single nested element will be
rolled up into a scalar rather than an array and therefore will not be
folded (since only arrays get folded).
</quote>

Setting ForceArray gives me exactly the same result as when there are two+
elements, so I don't see any bug here.


ahh, i missed that in the docs (going blind). i did notice that it
worked if i turned ForceArray on, but I thought it should do it if
ForceArray was off as well. The reason i turned it off was because it
seemed to disable GroupTag (or maybe i just missed something else in
the documentation, although i looked).

====
use strict; use warnings;

use XML::Simple;
use Data::Dumper;
$XML::Simple::pREFERRED_PARSER = 'XML::parser';

my $line = q{<application_log name="BranchFinder"><event t="123">} .
q{<data><item><name>zip</name><value>02109</value></item>} .
q{<item><name>method</name><value>Get</value></item>} .
q{<item><name>zip2</name><value>22222</value></item>} .
q{</data></event></application_log>};


# GroupTags eliminates extra level of indirection
# <data> must not contain attributes or non-<item> elements
my $ref = XMLin($line,
ForceArray => 1,
#KeyAttr => ['name'],
GroupTags => {data => 'item'},
);

print Dumper($ref);

__END__

$VAR1 = {
'name' => 'BranchFinder',
'event' => [
{
'data' => [
{
'item' => [
{
'value' => [
'02109'
],
'name' => [
'zip'
]
},
{
'value' => [
'Get'
],
'name' => [
'method'
]
},
{
'value' => [
'22222'
],
'name' => [
'zip2'
]
}
]
}
],
't' => '123'
}
]
};

======
whereas if i turn off ForceArray, GroupTag works...
$VAR1 = {
'name' => 'BranchFinder',
'event' => {
'data' => {
'zip' => {
'value' => '02109'
},
'zip2' => {
'value' => '22222'
},
'method' => {
'value' => 'Get'
}
},
't' => '123'
}
};

....maybe because with ForceArray ON, 'item' maps to a ref of an array
that contains 3 elements--hashrefs, while if ForceArray is OFF, 'item'
maps to a ref of a hash with 3 key/value pairs? i still don't see why
GroupTags would work with ForceArray OFF and not ON. the docs say "The
grouping element must not contain any attributes or elements other than
the grouped element." does this mean nested nested elements? if so,
then GroupTags should not work for ForceArray => 0 since there are
elements within <item>. if not, then GroupTag should work with
ForceArray => 1.

maybe i'm just too tired...
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top