in reply to Re: XML::Simple for sequence in xsd
in thread XML::Simple for sequence in xsd

Thanks Rob. I did use that. I thought it will work fine for me but it is showing me following error. Can't locate object method "TIESCALAR" via package "Tie::IxHash" I tried to figure out the error but I could not. I also installed the other required modules , I think I am missing somthing please help/suggest. Thanks. Sham.

Replies are listed 'Best First'.
Re^3: XML::Simple for sequence in xsd
by syphilis (Archbishop) on Aug 18, 2007 at 14:55 UTC
    Here's an example of how to use Tie::IxHash:
    use strict; use warnings; use Tie::IxHash; my %myhash; my %myotherhash; tie %myhash, 'Tie::IxHash'; for (my $i=0; $i<7; $i++) { $myhash{$i} = 2*$i; } my @keys = keys %myhash; print "@keys\n"; for (my $i=0; $i<7; $i++) { $myotherhash{$i} = 2*$i; } @keys = keys %myotherhash; print "@keys\n"; __END__ Output: 0 1 2 3 4 5 6 6 4 1 3 0 2 5
    Note that %myhash preserves the order, whereas %myotherhash (which is not tied to Tie::IxHash) does not preserve the order.

    If you still have trouble with the error you experienced it's probably best to provide some code that demonstrates the problem. (Try to provide a small script that demonstrates the problem.)

    Cheers,
    Rob
      It works in combination with XML::Simple:

      use strict; use warnings; use Tie::IxHash; use XML::Simple; my %myhash; tie %myhash, 'Tie::IxHash'; $myhash{foo1} = 'bar1'; $myhash{foo3} = 'bar3'; $myhash{foo2} = 'bar2'; $myhash{foo4} = 'bar4'; $myhash{foo5} = [qw(bar5a bar5b bar5c)]; print XMLout(\%myhash, NoSort => 1);

      And the output:

      <opt foo1="bar1" foo3="bar3" foo2="bar2" foo4="bar4"> <foo5>bar5a</foo5> <foo5>bar5b</foo5> <foo5>bar5c</foo5> </opt>

      And without the tie:

      <opt foo3="bar3" foo4="bar4" foo2="bar2" foo1="bar1"> <foo5>bar5a</foo5> <foo5>bar5b</foo5> <foo5>bar5c</foo5> </opt>

      Alternatively the data could be written with XML::Twig or other XML modules.

      Hi Rob, Tying up the hash is done fantastically with the Tie::IxHash module. But when I pass the this tied hash to the XML::Simple it no more follow the tie for the hash. I am trying to get the XML nodes in the sequence which I am following to create the hash elements. Following is the sample code and the output which I am trying to get correct result. If I am missing somewhere please suggest.
      use strict; use XML::Simple; use Data::Dumper; use Tie::IxHash; my $Request_data = {}; tie my %NewOrder_data , 'Tie::IxHash'; %NewOrder_data = ( 'IndustryType' => ['EC'], 'CurrencyCode' => ['840'], 'CurrencyExponent1' => ['1'], 'CurrencyExponent2' => ['2'], ); my @keys = keys %NewOrder_data; print "\n@keys\n"; my $xmlDS = { Request => [ { NewOrder => [ { %NewOrder_data, } ], } ], }; my $request_xml = eval { my $xs = new XML::Simple(keeproot => 1, SuppressEmpty => 1); $xs->XMLout($xmlDS); }; print STDERR "\n\nxml :- >\n" . Dumper($request_xml); __END__ OUTPUT :-------> IndustryType CurrencyCode CurrencyExponent1 CurrencyExponent2 xml :- > <Request> <NewOrder1> <CurrencyCode>840</CurrencyCode> <CurrencyExponent2>2</CurrencyExponent2> <IndustryType>EC</IndustryType> <CurrencyExponent1>1</CurrencyExponent1> </NewOrder1> </Request>
      Thanks, Sham
        For a start, there's one simple change that needs to be made. Replace:
        { %NewOrder_data, }
        with:
        \%NewOrder_data,
        Then, at least, $xmlDS will preserve the order that you assigned. (You can verify that with print Dumper($xmlDS), "\n";)

        However, the order gets lost in the final step when $request_xml is assigned its value. I couldn't find an easy way to deal with that ... perhaps XML::Simple also needs to 'use Tie::IxHash;' for this approach to work.

        Cheers,
        Rob