http://qs321.pair.com?node_id=345054

dwatson06 has asked for the wisdom of the Perl Monks concerning the following question:

I am writing a server that will need to take in an XML document. This document contains only one tag per name value.
ie
<USER> <LOGIN _AgeAtApplicationYears="33" firstName="Alice" lastName="Firsti +mer" address="111 test street" state="HI" zip="11111" phone="111-111- +1111" userName="testUser"> </LOGIN> </USER>

There will be only one USER coming in from the client at a time.

I am using Active Perl and currently looking at XML::Parser::Lite but it is space delimiting all values within the LOGIN tag. This throws off the addresses because there's spaces within the value.

I've seen several packages for parsing values that are assigned between the opening and closing tags but not ones embedded within the opening tag. (all the value assigments in the LOGIN tag.)


Do you have any suggestions on what XML package to use?
Thank you,
DWW

Replies are listed 'Best First'.
Re: XML package for parsing values in the opening tag.
by gjb (Vicar) on Apr 14, 2004 at 14:04 UTC

    XML::Simple will do the job nicely. The following code

    #!/usr/bin/perl use strict; use warnings; use Data::Dumper; use XML::Simple; my $xml = XMLin('login.xml'); print Dumper($xml);
    produces as output on your example:
    $VAR1 = { 'LOGIN' => { 'firstName' => 'Alice', '_AgeAtApplicationYears' => '33', 'phone' => '111-111-1111', 'state' => 'HI', 'zip' => '11111', 'userName' => 'testUser', 'lastName' => 'Firstimer', 'address' => '111 test street' } };

    To access e.g. the 'state' attribute, use $xml->{LOGIN}->{state}

    Hope this helps, -gjb-

    Update: What you call 'embedded tags' are actually termed attributes in XML speak ;)

      It's a parse of sheer beauty.
      Works perfectly.

      Thank you very much,
      DWW
Re: XML package for parsing values in the opening tag.
by matija (Priest) on Apr 14, 2004 at 14:03 UTC
Re: XML package for parsing values in the opening tag.
by mirod (Canon) on Apr 14, 2004 at 14:20 UTC

    Any proper XML module will do that: XML::Parser (on its way to deprecation except as a low-level layer used by more convenient modules), XML::LibXML, XML::Simple, XML::Smart, XML::Twig, XML::SAX::PurePerl... XML::Parser::Lite is _not_ a real XML parser, it is designed to parse SOAP messages, which only use a subset of the XML recommendation.

    As you mention you have problems with spaces in attributes, note that XML parsers are required to normalize attribute values, see The Annotated XML Specification. I don't think that's what your problem is here, but just in case, I thought I'd mention it.

      Thanks for the link to the specs.
      I found another problem when a tag name contains an underscore.
      <USER _City="testboro"></USER>
      When I call the value...
      print $xml->{USER}->{_CITY};
      The following is printed out when calling the value...
      "Use of uninitialized value"
      Tempted to strip out the underscores but that would be poor coding standards plus an underscore could be used as an actual data value. I will go through the specs now.
      DWW
        Dump the data with Data::Dumper and see what the problem is, most likely you will need to do print $xml->{'USER'}->{'_CITY'};


        -Waswas
        This is because XML::Simple by default cut the root node, since on XML we only have one root tag. Also you typed _CITY, upercase, that is different of _City, since XML is case sensitive. So, you actually should use:
        print $xml->{_City} ;

        If you use XML::Smart it has an option to load a XML and parse all the nodes and attributes in upercase or lowercase:

        use XML::Smart ; my $xml = XML::Smart->new(q`<USER _City="testboro"></USER>` , uperta +g=>1 , uperarg=>1); print $xml->dump_tree_ok ;
        Output:
        $VAR1 = { 'USER' => { '_CITY' => 'testboro' } };

        Graciliano M. P.
        "Creativity is the expression of the liberty".