Hash of hashes, of hashes, of arrays of hashes

Discussion in 'Perl Misc' started by Tim O'Donovan, Oct 27, 2005.

  1. 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
    Tim O'Donovan, Oct 27, 2005
    #1
    1. Advertising

  2. Tim O'Donovan

    Anno Siegel Guest

    Tim O'Donovan <> wrote in comp.lang.perl.misc:
    > 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
    --
    If you want to post a followup via groups.google.com, don't use
    the broken "Reply" link at the bottom of the article. Click on
    "show options" at the top of the article, then click on the
    "Reply" at the bottom of the article headers.
    Anno Siegel, Oct 27, 2005
    #2
    1. Advertising

  3. Tim O'Donovan

    Guest

    Tim O'Donovan <> wrote:
    > 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

    --
    -------------------- http://NewsReader.Com/ --------------------
    Usenet Newsgroup Service $9.95/Month 30GB
    , Oct 27, 2005
    #3
  4. Tim O'Donovan

    Guest

    Tim O'Donovan wrote:
    > 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
    , Oct 28, 2005
    #4
  5. Tim O'Donovan

    Guest

    wrote:
    > Tim O'Donovan wrote:
    > > 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
    , Oct 28, 2005
    #5
  6. Tim O'Donovan

    Guest

    On 27 Oct 2005 17:59:48 -0700, "" <>
    wrote:

    >
    > wrote:
    >> Tim O'Donovan wrote:
    >> > 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.

    >> >
    >> > Any advice would be greatly appreciated.
    >> >
    >> > Thanks.
    >> >
    >> >
    >> > Kind regards,
    >> > Tim O'Donovan
    , Oct 28, 2005
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. rp
    Replies:
    1
    Views:
    520
    red floyd
    Nov 10, 2011
  2. Tore Aursand
    Replies:
    3
    Views:
    552
    Anno Siegel
    Sep 16, 2003
  3. Scott  Gilpin
    Replies:
    2
    Views:
    219
  4. Perl Learner

    Hashes of hashes or just one hash ?

    Perl Learner, Jun 8, 2005, in forum: Perl Misc
    Replies:
    11
    Views:
    214
  5. Replies:
    3
    Views:
    206
Loading...

Share This Page