Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Generating elements with attributes and contents using XML::Smart

by pfaut (Priest)
on Aug 19, 2004 at 02:52 UTC ( [id://384174]=perlquestion: print w/replies, xml ) Need Help??

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

I am reading data from a database and attempting to create XML using XML::Smart. I'm having some problems creating elements that have attributes and textual content.

I would like to create things along the lines of:

<phone type="home">555-1234</phone>

But I can't quite get it to work. I either lose the attribute altogether or it gets inserted as a tag inside the phone element's contents. It might have been confusing it a little that the 'phone' element was defined with a 'type' attribute and I also had a 'type' element but that had nothing to do with 'phone' element. I tried changing the attribute to 'xxx' but then it never showed up in the output.

As far as I can tell, it's valid XML. Is it possible to create this using XML::Smart with a DTD?

From the DTD:

<!ELEMENT customer (phone+)> <!ELEMENT phone (#PCDATA)> <!ATTLIST phone type PCDATA #REQUIRED>

90% of every Perl application is already written.
dragonchild

Replies are listed 'Best First'.
Re: Generating elements with attributes and contents using XML::Smart
by leriksen (Curate) on Aug 19, 2004 at 05:03 UTC
    I dont know the exact form of the (presumably) hash you are getting back form the DB, but here is one way for a fairly flat hash

    #!/usr/bin/perl -w use strict; use Data::Dumper; use XML::Simple qw(:strict); my $data = { phone => '555-1234', type => 'home' }; print STDERR XML::Simple->new(KeyAttr => {phone => 'type'}, RootName => 'phone', XMLDecl => 1, ContentKey => 'phone', )->XMLout($data);
    output

    /usr/bin/perl -w "/home/le6303/src/perl/phone.pl" <?xml version='1.0' standalone='yes'?> <phone type="home">555-1234</phone>
    Update : changed the KeyAttr to the more preferred hash form

    use brain;

Re: Generating elements with attributes and contents using XML::Smart
by gmpassos (Priest) on Aug 19, 2004 at 13:19 UTC
    This will create what you want:
    use XML::Smart ; my $xml = new XML::Smart() ; $xml->{phone} = '555-1234' ; $xml->{phone}{type} = 'home' ; print $xml->data ;
    Output:
    <?xml version="1.0" encoding="iso-8859-1" ?> <?meta name="GENERATOR" content="XML::Smart/1.6.8 Perl/5.006001 [MSWin +32]" ?> <phone type="home">555-1234</phone>
    See the method apply_dtd() in the XML::Smart documentation to apply automatically a DTD to all your tree.

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

      That's not working for me. The 'type' attribute gets lost.

      The code:

      use XML::Smart; my $xml = XML::Smart->new; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml->apply_dtd(<<EOF); <?xml version="1.0" ?> <!DOCTYPE customer [ <!ELEMENT customer (phone+)> <!ELEMENT phone (#PCDATA)> <!ATTLIST phone type PCDATA #REQUIRED> ]> EOF print $xml->data;

      The results:

      <?xml version="1.0" encoding="iso-8859-1" ?> <?meta name="GENERATOR" content="XML::Smart/1.6.6 Perl/5.008 [MSWin32] +" ?> <!DOCTYPE customer [ <!ELEMENT customer (phone+)> <!ELEMENT phone (#PCDATA)> <!ATTLIST phone type PCDATA #REQUIRED> ]> <customer> <phone>555-1234</phone> </customer> Use of uninitialized value in print at testxml.pl line 19.

      Line 19 is print $xml->data.

      90% of every Perl application is already written.
      dragonchild
        The error is in your DTD syntax! You can't have PCDATA as attribute, since PCDATA is only for contents. You should use CDATA.

        When you apply_dtd(), if some ELEMENT or ATTRIBUTE is not defined in the DTD it will be removed from the tree! So, type is removed since the line ATTLIST is wrong.

        This code will work:

        use XML::Smart; my $xml = XML::Smart->new; $xml->{customer}{phone} = "555-1234"; $xml->{customer}{phone}{type} = "home"; $xml->apply_dtd(<<EOF); <?xml version="1.0" ?> <!DOCTYPE customer [ <!ELEMENT customer (phone+)> <!ELEMENT phone (#PCDATA)> <!ATTLIST phone type CDATA #REQUIRED> ]> EOF print $xml->data;
        Output:
        <?xml version="1.0" encoding="iso-8859-1" ?> <?meta name="GENERATOR" content="XML::Smart/1.6.8 Perl/5.006001 [MSWin +32]" ?> <!DOCTYPE customer [ <!ELEMENT customer (phone+)> <!ELEMENT phone (#PCDATA)> <!ATTLIST phone type CDATA #REQUIRED> ]> <customer> <phone type="home">555-1234</phone> </customer>

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

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://384174]
Approved by ysth
Front-paged by ysth
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others cooling their heels in the Monastery: (7)
As of 2024-04-19 09:07 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found