Beefy Boxes and Bandwidth Generously Provided by pair Networks
Clear questions and runnable code
get the best and fastest answer
 
PerlMonks  

XML::Simple how do i keep the same xml format (Values and Attributs)?

by tobias_hofer (Friar)
on Jun 14, 2013 at 10:04 UTC ( #1038934=perlquestion: print w/ replies, xml ) Need Help??
tobias_hofer has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks.

I am using XML::Simple for xml processing.
I read in following from a file:
<TABLE> <TABLE-CAPTION ID="ID64706055682598"> <LONG-NAME>TABLE NAME</LONG-NAME> </TABLE-CAPTION> <TGROUP COLS="4"> <COLSPEC COLNUM="1" COLNAME="col1" COLWIDTH="1.00*"/> <COLSPEC COLNUM="2" COLNAME="col2" COLWIDTH="1.00*"/> <COLSPEC COLNUM="3" COLNAME="col3" COLWIDTH="1.00*"/> <COLSPEC COLNUM="4" COLNAME="col4" COLWIDTH="1.00*"/> <TBODY> <ROW> <ENTRY COLNAME="col1">A</ENTRY> <ENTRY COLNAME="col2">B</ENTRY> <ENTRY COLNAME="col3">C</ENTRY> <ENTRY COLNAME="col4">D</ENTRY> </ROW> <ROW> <ENTRY COLNAME="col1">E</ENTRY> <ENTRY COLNAME="col2">F</ENTRY> <ENTRY COLNAME="col3">G</ENTRY> <ENTRY COLNAME="col4">H</ENTRY> </ROW> </TBODY> </TGROUP> </TABLE>
And I want to write the same to file. Thing is, that when i am putting the xml to file some values become xml-attributes.
So in the end i got this:
<TABLE> <TABLE-CAPTION ID="ID64706055682598" LONG-NAME="TABLE NAME" /> <TGROUP COLS="4"> <COLSPEC COLNAME="col1" COLNUM="1" COLWIDTH="1.00*" /> <COLSPEC COLNAME="col2" COLNUM="2" COLWIDTH="1.00*" /> <COLSPEC COLNAME="col3" COLNUM="3" COLWIDTH="1.00*" /> <COLSPEC COLNAME="col4" COLNUM="4" COLWIDTH="1.00*" /> <TBODY> <ROW> <ENTRY COLNAME="col1">A</ENTRY> <ENTRY COLNAME="col2">B</ENTRY> <ENTRY COLNAME="col3">C</ENTRY> <ENTRY COLNAME="col4">D</ENTRY> </ROW> <ROW> <ENTRY COLNAME="col1">E</ENTRY> <ENTRY COLNAME="col2">F</ENTRY> <ENTRY COLNAME="col3">G</ENTRY> <ENTRY COLNAME="col4">H</ENTRY> </ROW> </TBODY> </TGROUP> </TABLE>
This read about parameters to XML Simple like VauleAttr and KeyAttr but it seems to have no effect. As far as i have understood i can define with ValueAttr what should be printed as Value and not as Attribute.. Maybe i have misunderstood this API? The same idea i have form KeyAttr so i can define what hash-keys are in the end Attributes and no values..

I am stuck in the middle, any help is highly welcome!
Here my prototype where i read in the an xml-file with the content of the first XML-structure i have put here. By this i can check if (at the end) i will get the same XML-structure back when looking at $xml:

use XML::Simple; use strict; my $xmlParser = new XML::Simple( RootName => 'TABLE', KeepRoot=>1, ValueAttr=>{ 'TABLE-CAPTION' => 'LONG-NAME', }); my $data = $xmlParser->XMLin("testtable.xml"); my $xml = $xmlParser->XMLout($data); print "stop";

Any help is highly welcome!

Regards!
Tobias

Comment on XML::Simple how do i keep the same xml format (Values and Attributs)?
Select or Download Code
Re: XML::Simple how do i keep the same xml format (Values and Attributs)? (XML::Rules)
by Anonymous Monk on Jun 14, 2013 at 10:08 UTC
Re: XML::Simple how do i keep the same xml format (Values and Attributs)?
by tobias_hofer (Friar) on Jun 14, 2013 at 10:45 UTC
    I cannot switch to XML::Rules.. i need to get this done by XML::Simple..
    I wonder why this attribute and value stuff is working in all xml-tags but this 'LONG-NAME' tag..
    ???

      Then you are stuck between a rock and a hard place. You don't want to switch away from XML::Simple, yet the author of XML::Simple freely admits that it's not suitable for the sort of task you're describing and recommends other modules instead. Quotes from the documentation:

      "XML::Simple is able to present a simple API because it makes some assumptions on your behalf. These include:

      • [...]
      • "You don't want fine-grained control of the formatting of generated XML
      • [...]

      "In a serious XML project, you'll probably outgrow these assumptions fairly quickly.

      [...]

      "For event based parsing, use SAX (do not set out to write any new code for XML::Parser's handler API - it is obselete).

      "For tree-based parsing, you could choose between the 'Perlish' approach of XML::Twig and more standards based DOM implementations - preferably one with XPath support such as XML::LibXML."

      Personally I use XML::LibXML for virtually any XML-handling task that's thrown my way, and am rarely disappointed by it.

      package Cow { use Moo; has name => (is => 'lazy', default => sub { 'Mooington' }) } say Cow->new->name
        Yes, you are right..
        If I am lucky I can convince people installing this package so I can switch to it. Thanks a lot!

        However, I have found a solution :-))

        XML Simple puts nearly every hash as an XML-attribute. But not if its pointing to another hash, example
        :
        $tdata->{'TABLE-CAPTION'} = {'ID' => $_id, 'LONG-NAME' => {content => +'Test results'}};
        Using content will create another XML-tag and not an attribute. But for using this I had to configure XML-Simple like this.
        my $xmlParser = new XML::Simple( RootName => 'TABLE', KeepRoot=>1, ValueAttr=>{ 'TABLE-CAPTION' => 'ID', 'ContentKey' => 'content', }
        Now its working fine, look at this: ^^
        P>Testresults:</P><TABLE> <TABLE-CAPTION ID="ID42.401123046875"> <LONG-NAME>Testresults</LONG-NAME> </TABLE-CAPTION> <TGROUP COLS="4"> <COLSPEC COLNAME="test-id" COLNUM="0" COLWIDTH="1.00*" /> <COLSPEC COLNAME="status" COLNUM="1" COLWIDTH="1.00*" /> <COLSPEC COLNAME="test-spec" COLNUM="2" COLWIDTH="1.00*" /> <COLSPEC COLNAME="requirement-ids" COLNUM="3" COLWIDTH="1.00*" /> <TBODY> <ROW> <ENTRY COLNAME="test-id"> ...

        Thank you very much for all your hints and tips!

        Best regards!!
        Tobias

      XML::Rules is a single .pm file and its only non-core dependency is XML::Parser which you most probably already have so if you can create/upload your script, you can "install"/upload XML::Rules. No compilation or configuration required, you just need to put the Rules.pm into a directory named XML in one of the directories listed by perl -e "print join qq{\n}, @INC".

      Yes, even you can use CPAN

      Jenda
      Enoch was right!
      Enjoy the last years of Rome.

Re: XML::Simple how do i keep the same xml format (Values and Attributs)?
by hdb (Prior) on Jun 14, 2013 at 11:01 UTC

    There is also NoAttr => 1 in XML::Simple but that goes into the other extreme.

      I had occasion to use both the OP's solution and NoAttr => 1 on a project where rewriting existing XML::Simple to use a different module wasn't an option.

      When writing new modules for the project, I used XML::Twig or XML::LibXML. Didn't know about XML::Rules; I'll have to check it out.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1038934]
Approved by marto
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others cooling their heels in the Monastery: (9)
As of 2015-07-07 00:43 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (86 votes), past polls