need help using XML::Simple::XMLOut() and XML::Simple::XMLin()

Posted on 2005-04-23
Last Modified: 2013-11-19

  I am a complete newbie when it comes to this. I would like to use XML::Simple to write a hash table to an .xml file. For me, this is best explained by examples:

the hash table is $self inside sub new():

sub new {
      my $type = shift;
      my $class = ref ($type) || $type;
      my @players =();
      #my $refPlayers = shift;
      my $bjRules = shift;
      my $dealer = new BJDealer($bjRules);
      my $self = {players => \@players,
                        current_player => undef,
                        rules => $bjRules,
                        dealer => $dealer,
                        deck => undef
      return $self;

I try to convert using this subroutine I wrote:


sub perl_to_xml {
  my $self = shift;
  my $path = "c:\\testXMLOUT.xml";
  open my $fh, '>:encoding(iso-8859-1)', $path or die "open($path): $!";
  XMLout($self, OutputFile => $fh);

  return 1;


However, when I run the following test script:

# code fragment:
my $simul = new BJSimulation();


I get the following error message:
Can't locate object method "print" via package "IO::Handle" at c:/Perl/site/lib/XML/ line 540.

I'm not even sure how to diagnose the error message. I am unaccustom to seeing error messages generated by a PERL internal like IO::Handle.

Any advice would be greatly appreciated! I want to start with getting XMLOut working, and then turn to XMLIn.

Question by:sapbucket
    LVL 84

    Expert Comment

    # I will try to see if I can find out why you are getting the error, but meanwhile you could do it this way insead:

      print $fh XMLout($self);
    LVL 84

    Accepted Solution

    #To get rid of the error
    use IO::Handle;
    LVL 3

    Author Comment

    that made it work.

    i get an error when trying to open it with the Windows XP XML editor. The xml has tags that are numeric (0..number_hands), which it doesn't like. But, this seems somewhat odd to me because the source of the tags is an anonymous array nested in a hash table. Should be very common for anonymous hashes and arrays to be converted to xml, however, in this case it is generating non-XML-editor conforming xml.

    (error message)
    The XML page cannot be displayed
    Cannot view XML input using XSL style sheet. Please correct the error and then click the Refresh button, or try again later.
    A name was started with an invalid character. Error processing resource 'file:///C:/testXMLOUT.xml'. Line 6, Position 8

    in notepad it looks like this:
      <dealer current_hand="0" number_hands="1" upcard="3S">
        <hands name="table">
        <rules doubleAfterPairSplit="1" doublingNumCards="0" doublingRules="2" earlySurrender="0" hitSplitAce="1" insurance="1" lateSurrender="1" natural="2" numDecks="1" penetration="100" resplitAce="1" resplitPairs="1" soft17="0" softDoubling="1" splitAce="1" splitPairs="1" ties="0" />
      <deck numDecks="1" penetration="100">
      <players bank="1000" buyin="1000" current_hand="0" number_hands="1" player_id="player 1">
        <hands name="table">
      <players bank="500" buyin="500" current_hand="0" number_hands="1" player_id="player 2">
        <hands name="table">
      <rules doubleAfterPairSplit="1" doublingNumCards="0" doublingRules="2" earlySurrender="0" hitSplitAce="1" insurance="1" lateSurrender="1" natural="2" numDecks="1" penetration="100" resplitAce="1" resplitPairs="1" soft17="0" softDoubling="1" splitAce="1" splitPairs="1" ties="0" />

    and the anonymous hash "object" is derived from perldoc perlreftut (a hash with anonymous arrays references (CITIES) for the values and scalars for the keys (COUNTRIES)):
    package Hashtable;
    use strict;

    sub new {
          my $type = shift;
          my $class = ref($type) || $type;
          my $self={ table=>{}};
          bless ($self, $class);
          return ($self);

    I think I know the solution. If you have a hash using keys that are equal to (0..number_of_keys_in_hash), than you should just use an array. But, dang it. I have all that code already written and it works great! I could convert '1' to "one" and '2' to "two", etc. Or use the $player_id as the key instead of '1','2','3', etc. And then I could have a lookup-hash that uses the $player_id as a key to find the value ('1','2','3').  That would be a subroutine called lookup_player_index().

    I didn't think it would be so picky.

    Any ideas on that?

    LVL 84

    Expert Comment

    XMLout($hashref) should produce conforming XML when $hashref was created by XMLin() from conforming XML,
    but as you've seen, not all possible hash keys are valid XML tags.

    If you want to start with an arbitrary Perl data structure,

    use XML::Dumper;
    print $fh pl2xml( $self );
    #should produce valid XML that can be converted back with xml2pl(pl2xml( $self ));
    LVL 3

    Author Comment

    yes that worked good for viewing the xml. That tagging system is not what my DataSet expects, unfortunately. XML::Simple was more on par with the type of XML i want to use.

    I have been looking at xml books. It would seem that I should take greater care in the design of my hashtables so that the xml is structured better (and does not use invalid characters). I really am a newb at this!
    LVL 3

    Author Comment

    Do you know how to link the XML to a VB.NET database by any chance?
    LVL 3

    Author Comment

    OK, I figured out how to link XML to a VB.NET dataset.

    It turns out that the Xml I am generating () is not compliant with W3C schema standards.

    I am curious to know what people are doing with the xml generated by XML::Simple. From my point of view, it generates "garbage" xml because it is malformed (non compliant).

    I wonder if there is a proper way to construct a hash so that the XML generated by XML::Simple is W3C compliant? Or maybe there is a way of setting options in XML::Simple to make it more compliant? Or maybe there is a better module than XML::Simple?

    What would a "W3C Compliant" hash look like (I know, we must extend our thought here). Could there be a proper idiom for hash design that would create perfect, W3C compliant xml? What would be the algorithm for constucting such a hash? I think it would be *incredibly* useful! For me, the useful application would be that I can develop my applications using a console and perl (all text based), and when I am ready to link it to a GUI interface (like VB.NET or ASP.NET - programs that do not "glue" well with Perl). I can simply perl2xml each object hash and link the generated xml to a dataset. Since each object contains all of the data\content for that object within the hash (blessed hash reference, whatever) I get a perfect xml description of the current state of each object. As click_events occur and what not, the xml acts as a storage for next state and current state information/content to be passed between Perl and .NEt. Sound good to you? I like it because it skips the whole server/client model, AND I don't have to write any SQL statements OR deal with silly OS environment variables (so it would be platform independent too). I guess this is what XML has promised all along - I just can't make it practical with Perl yet because I can't generate compliant XML.

    Any thoughts experts? I do not want to re-invent the wheel here. Maybe XML::Simple *does* create perfect, W3C compliant xml, and it is the programmer (me) that needs some re-work. Sharing your thoughts on proper hash design (in terms of XML generation) would benefit me the best.

    LVL 3

    Author Comment

    LVL 84

    Expert Comment

    perldoc XML::Simple

           Some care is required in creating data structures which will be passed
           to "XMLout()".  Hash keys from the data structure will be encoded as
           either XML element names or attribute names.  Therefore, you should use
           hash key names which conform to the relatively strict XML naming rules:

           Names in XML must begin with a letter.  The remaining characters may be
           letters, digits, hyphens (-), underscores (_) or full stops (.).  It is
           also allowable to include one colon (:) in an element name but this
           should only be used when working with namespaces (XML::Simple can only
           usefully work with namespaces when teamed with a SAX Parser).

           You can use other punctuation characters in hash values (just not in
           hash keys) however XML::Simple does not support dumping binary data.

           If you break these rules, the current implementation of "XMLout()" will
           simply emit non-compliant XML which will be rejected if you try to read
           it back in.  (A later version of XML::Simple might take a more proac-
           tive approach).

           Note also that although you can nest hashes and arrays to arbitrary
           levels, circular data structures are not supported and will cause
           "XMLout()" to die.

           If you wish to 'round-trip' arbitrary data structures from Perl to XML
           and back to Perl, then you should probably disable array folding (using
           the KeyAttr option) both with "XMLout()" and with "XMLin()".  If you
           still don't get the expected results, you may prefer to use XML::Dumper
           which is designed for exactly that purpose.

           Refer to "WHERE TO FROM HERE?" if "XMLout()" is too simple for your
    LVL 3

    Author Comment

    I read that too. There should be more caveats tho. The actual (strict,compliant) method of nesting hashes and arrays should of been addressed. He makes mention of array folding, which is a good start, but should have followed up with examples.

    I've got a meeting tomorrow with a guy who wrote a book on XML and VB.NET. It should lead me up to the proper idiom. I'll post here when I figure it out.

    Not all of us (or should I say, none of us!) can program like you ozo. You are a rare bird indeed!
    LVL 3

    Author Comment

    OK, this is the wrong path to take.

    I am trying to have a Perl application talk to a .NET application via XML. I think better would be to use Tie::DBI or something similar. I'm going to post another question, similar intent, but completely different design pattern.

    LVL 3

    Author Comment

    Thanks for the help ozo, I am giving up on xml and focusing on using relational databases (MySql) instead. Couldn't get things to work at all using xml.

    Write Comment

    Please enter a first name

    Please enter a last name

    We will never share this with anyone.

    Featured Post

    How your wiki can always stay up-to-date

    Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
    - Increase transparency
    - Onboard new hires faster
    - Access from mobile/offline

    I will show you how to create a ASP.NET Captcha control without using any HTTP HANDELRS or what so ever. you can easily plug it into your web pages. For Example a = 2 + 3 (where 2 and 3 are 2 random numbers) Session("Answer") = 5 then we…
    Checking the Alert Log in AWS RDS Oracle can be a pain through their user interface.  I made a script to download the Alert Log, look for errors, and email me the trace files.  In this article I'll describe what I did and share my script.
    The viewer will learn how to create and use a small PHP class to apply a watermark to an image. This video shows the viewer the setup for the PHP watermark as well as important coding language. Continue to Part 2 to learn the core code used in creat…
    The viewer will learn the benefit of using external CSS files and the relationship between class and ID selectors. Create your external css file by saving it as style.css then set up your style tags: (CODE) Reference the nav tag and set your prop…

    779 members asked questions and received personalized solutions in the past 7 days.

    Join the community of 500,000 technology professionals and ask your questions.

    Join & Ask a Question

    Need Help in Real-Time?

    Connect with top rated Experts

    12 Experts available now in Live!

    Get 1:1 Help Now