Hash of hashes, of hashes, of arrays of hashes

T

Tim O'Donovan

Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:


#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);


The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

and how many elements are present in:

$xmldoc{doc1}{customer}

and so on.

I was then planning on looping through each section and using the data
to contruct the XML.

For reference, here is the dumped output of %xmldoc:

$VAR1 = 'doc1';
$VAR2 = {
'customer' => [
{
'format' => 'int',
'name' => 'count'
},
{
'format' => 'text',
'name' => 'unit'
}
],
'order' => [
{
'format' => 'date',
'name' => 'expected'
}
]
};

Any advice would be greatly appreciated.

Thanks.


Kind regards,
Tim O'Donovan
 
A

Anno Siegel

Tim O'Donovan said:
Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:


#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);


The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

and how many elements are present in:

$xmldoc{doc1}{customer}

and so on.

I was then planning on looping through each section and using the data
to contruct the XML.

Look up "perldoc -f keys". In scalar context it gives you the number
of keys in a hash, in list context it returns a list of all keys to
loop over.

Anno
 
X

xhoster

Tim O'Donovan said:
Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:

#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);

The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

$xmldoc{doc1} is a hashref. hashref's don't have keys, so you need to
dereference it, using %{}. Then you need to ask how many keys are in it by
using "keys" in a scalar context.

my $size=keys %{$xmldoc{doc1}};

Xho
 
R

robic0

Tim said:
Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:


#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);


The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

and how many elements are present in:

$xmldoc{doc1}{customer}

and so on.

I was then planning on looping through each section and using the data
to contruct the XML.

I think the structure looks pretty tame here, but its not as simple as
you may think to do this. Its not a simple looping through the
data structures. Its itterative, is usually done with respect to
closures, creating a string for an inner block and substituting that
string for that inner block, which was an array. The next time through,
another block is converted, until finally you have a single string that
is your XML. In the event you would like to do it right, you may want
to check out XML:Simple... gluck!
For reference, here is the dumped output of %xmldoc:

$VAR1 = 'doc1';
$VAR2 = {
'customer' => [
{
'format' => 'int',
'name' => 'count'
},
{
'format' => 'text',
'name' => 'unit'
}
],
'order' => [
{
'format' => 'date',
'name' => 'expected'
}
]
};

Any advice would be greatly appreciated.

Thanks.


Kind regards,
Tim O'Donovan
 
R

robic0

Tim said:
Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:


#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);


The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

and how many elements are present in:

$xmldoc{doc1}{customer}

and so on.

I was then planning on looping through each section and using the data
to contruct the XML.

I think the structure looks pretty tame here, but its not as simple as
you may think to do this. Its not a simple looping through the
data structures. Its itterative, is usually done with respect to
closures, creating a string for an inner block and substituting that
string for that inner block, which was an array. The next time through,
another block is converted, until finally you have a single string that
is your XML. In the event you would like to do it right, you may want
to check out XML:Simple... gluck!
Just to clarify, you might drill into the arrays looking for
a child that has no arrays (or refs to arrays). When you find one you
create an xml string from the child array, then substitute that
string into the parent array. So in one pass maybe you find 2 out of
10.
Then you repeat from the begining again. The problem comes from unamed
(anonymous) arrays. You have to assign names (tags) to them. You also
have to unhook the array you are replacing too via a undef that is
ignored on subsequent passes. I'm only suggesting a possible way to do
this, but there are modules out there if you are looking for a quick
solution.
For reference, here is the dumped output of %xmldoc:

$VAR1 = 'doc1';
$VAR2 = {
'customer' => [
{
'format' => 'int',
'name' => 'count'
},
{
'format' => 'text',
'name' => 'unit'
}
],
'order' => [
{
'format' => 'date',
'name' => 'expected'
}
]
};

Any advice would be greatly appreciated.

Thanks.


Kind regards,
Tim O'Donovan
 
R

robic0

Tim said:
Hi,

I'm trying to create a data structure that will (eventually) make it
easier to create a series of slightly different XML documents. The
structure will effectively hold a template.

Here's a section of code I am stuck on:


#!/usr/bin/perl -w

use strict;
use Data::Dumper;

my %xmldoc = (
doc1 => {
customer => [{name => 'count', format => 'int'},
{name => 'unit', format => 'text'},
],
order => [{name => 'expected', format => 'date'},
],
},
#etc
);


The problem I am having is determining how many keys are present in:

$xmldoc{doc1}

and how many elements are present in:

$xmldoc{doc1}{customer}

and so on.

I was then planning on looping through each section and using the data
to contruct the XML.

I think the structure looks pretty tame here, but its not as simple as
you may think to do this. Its not a simple looping through the
data structures. Its itterative, is usually done with respect to
closures, creating a string for an inner block and substituting that
string for that inner block, which was an array. The next time through,
another block is converted, until finally you have a single string that
is your XML. In the event you would like to do it right, you may want
to check out XML:Simple... gluck!
Just to clarify, you might drill into the arrays looking for
a child that has no arrays (or refs to arrays). When you find one you
create an xml string from the child array, then substitute that
string into the parent array. So in one pass maybe you find 2 out of
10.
Then you repeat from the begining again. The problem comes from unamed
(anonymous) arrays. You have to assign names (tags) to them. You also
have to unhook the array you are replacing too via a undef that is
ignored on subsequent passes. I'm only suggesting a possible way to do
this, but there are modules out there if you are looking for a quick
solution.
For reference, here is the dumped output of %xmldoc:

$VAR1 = 'doc1';
$VAR2 = {
'customer' => [
{
'format' => 'int',
'name' => 'count'
},
{
'format' => 'text',
'name' => 'unit'
}
],
'order' => [
{
'format' => 'date',
'name' => 'expected'
}
]
};
One more clarification after pondering.
Given VAR2 above (from Dumpster), to go the other way
to xml, this would follow:
-------------------------------------
1st pass:

$VAR2 = {
'customer' => '<formatblock1>
<format>int</format><name>count</name>
</formatblock1>
<formatblock2>
<format>text</format><name>unit</name>
</formatblock2>',

'order' => '<formatblock>
<format>date</format><name>expected</name>
</formatblock>'
};

2nd pass:

$VAR2 = '<block>
<customer>
<formatblock1>
<format>int</format><name>count</name>
</formatblock1>
<formatblock2>
<format>text</format><name>unit</name>
</formatblock2>
</customer>
<order>
<formatblock>
<format>date</format><name>expected</name>
</formatblock>
</order>
</block>';
-------------------------------
This is easy to do programtically. It is itterative.
However, you can clearly see the optimizations made with
formatblock1, formatblock2 (and formatblock) above because of
the "unamed" referenced arrays. In that regard, its obvious
that using these methods and going back and forth between
reading and writing xml, and know these assumptions must be
made will not give consistent results that you can program
to. Xml tag name creation can't be fully known sometimes from
nested anonymouse arrays and hashes.
With these xml packages like XML:Simple assumptions of
naming have be made. Usually if you know the layout of the major
structural components your can roll your own xml creator.
Probably in a "fully" named structure paradigm (C) you
would have better results, not necessarily so in Perl.
Anyway, just clearing that up. Read all the docs on XML:Simple
for a better understanding going from Perl to XML.
Its always easier to go from XML to Perl, especially with SAX
and your known tags, to "ingest" data. If you do go out to
XML from perl be aware that intermediate hand modification
steps probably will be necessary.
 

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

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,902
Latest member
Elena68X5

Latest Threads

Top