Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl: the Markov chain saw
 
PerlMonks  

Re: Building XML with tab delimited

by Marshall (Canon)
on Aug 11, 2016 at 04:18 UTC ( [id://1169554]=note: print w/replies, xml ) Need Help??


in reply to Building XML with tab delimited

I do not have a solution, but I have some suggestions that may help.

  • I reformatted the code to a more consistent indentation style. You can use a different one, but consistency helps me in the understanding.
  • I converted the code to use the DATA segment for reading instead of an input file.
  • I added "use warnings;" this showed a number of issues. You need to skip these first 2 lines of the input file. Use of prototypes, e.g.sub buildXMLElements() {} should just be sub buildXMLElements {}. However this is not the main problem.
  • I added in some print statements that may help somebody else figure out what the problem is. I don't see it at the moment.
My code produces the output to STDERR:
pin not equal appending first Charge <REPORT TYPE="AB"><REASON1>data1</REASON1><REASON2>data2</REASON2><REA +SON3>data3</REASON3><PERSON><PIN>Pin 1</PIN><NAME>data5</NAME><ZIP>da +ta6</ZIP></PERSON><CHARGE><DATE>data7</DATE><TIME>data8</TIME></CHARG +E></REPORT> pin equal <REPORT TYPE="AB"><CHARGE><DATE>data9</DATE><TIME>data10</TIME></CHARG +E></REPORT> appending a Charge pin equal <REPORT TYPE="AB"><CHARGE><DATE>data11</DATE><TIME>data12</TIME></CHAR +GE></REPORT> appending a Charge writing document Process completed successfully
And output file:
<?xml version="1.0"?> <XML_FILE><REPORT TYPE="AB"><REASON1>data1</REASON1><REASON2>data2</RE +ASON2><REASON3>data3</REASON3><PERSON><PIN>Pin 1</PIN><NAME>data5</NA +ME><ZIP>data6</ZIP></PERSON><CHARGE><DATE>data7</DATE><TIME>data8</TI +ME></CHARGE></REPORT></XML_FILE>
reformatted code:
use strict; use warnings; use Data::Dumper; use XML::LibXML; #my $READFILENAME = "SomeDir\\data.txt"; my $WRITEFILENAME = "test.xml"; my $doc = XML::LibXML::Document->new('1.0'); my $root = $doc->createElement("XML_FILE"); open (FILEWRITE, ">$WRITEFILENAME"); # open (READFILE, $READFILENAME); my $copy_person_pin = "XX"; <DATA>;<DATA>; ############################ while (my $line = <DATA>) { chomp $line; my @data = split(/\t/,$line); my $reason1 = $data[0]; my $reason2 = $data[1]; my $reason3 = $data[2]; my $person_pin = $data[3]; my $name = $data[4]; my $zip = $data[5]; my $date = $data[6]; my $time = $data[7]; my $report = $doc->createElement("REPORT"); $report->setAttribute('TYPE'=>'AB'); if ($person_pin ne $copy_person_pin) { # Build the Report tags my @sortedReportTag = qw ( REASON1 REASON2 REASON3); my %reportHashTags; @reportHashTags { @sortedReportTag } = ($reason1, $reason2, $reason3 ); + buildXMLElements(\@sortedReportTag, \%reportHashTags, $report); + $root-> appendChild($report); # Build the element for Person Tag my $person = $doc->createElement("PERSON"); my @sortedPersonTag = qw ( PIN NAME ZIP); my %personHashTags; @personHashTags { @sortedPersonTag } = ($person_pin, $name, $zip ); # Build the elements for Person Tag buildXMLElements(\@sortedPersonTag, \%personHashTags, $person); $report-> appendChild($person); # Build the elements for Charge Tag my $charge = $doc->createElement("CHARGE"); my @sortedChargeTag = qw ( DATE TIME ); my %chargeHashTags; @chargeHashTags { @sortedChargeTag } = ($date, $time ); buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge); $report-> appendChild($charge); $copy_person_pin = $person_pin; print STDERR "pin not equal\n"; print STDERR "appending first Charge\n"; print STDERR $report->toString(),"\n"; # returns a character string } else { print STDERR "pin equal\n"; my $charge = $doc->createElement("CHARGE"); my @sortedChargeTag = qw ( DATE TIME ); my %chargeHashTags; @chargeHashTags { @sortedChargeTag } = ($date, $time ); # Build the elements for Charge Tag + buildXMLElements(\@sortedChargeTag, \%chargeHashTags, $charge); $report-> appendChild($charge); print STDERR $report->toString(),"\n"; # returns a character string + print STDERR "appending a Charge\n"; } } print STDERR "writing document\n"; $doc->setDocumentElement($root); # Write the XML to a file print FILEWRITE ($doc->toString()); close FILEWRITE; sub buildXMLElements { my($elementTags, $hashTags, $parentElement) = @_; for my $name (@$elementTags) { my $reportTag = $doc->createElement($name); my $reportValue = $hashTags->{$name}; $reportTag->appendTextNode($reportValue); $parentElement->appendChild($reportTag); } } __DATA__ Reason1 Reason2 Reason3 Pin Name Zip Date Time data1 data2 data3 Pin 1 data5 data6 data7 data8 data1 data2 data3 Pin 1 data5 data6 data9 data10 data1 data2 data3 Pin 1 data5 data6 data11 data12

Replies are listed 'Best First'.
Re^2: Building XML with tab delimited
by sannag (Sexton) on Aug 11, 2016 at 04:32 UTC
    Thank you very much for the effort. Once thing I noticed is it matters where I place the line "my $report = $doc->createElement("REPORT");" if I placed it outside the while loop and then remove the "else" to replace it with the statement "if ($person_pin eq $copy_person_pin)" then all my 'CHARGE' tag start appearing in the XML but then the XML struct is altered. I am beginning to believe XML:LibXML is very funky.
      This is actually a very normal thing. I saw the comment in the code. You cannot "sometimes" and "sometimes not" create a "my" variable in some conditional statement and expect that variable will around for use elsewhere. If you do that, you will only have use of it during that "if" clause only. If you violate that, then I think the results are undefined and unpredictable. Maybe I didn't understand what you meant here. This is a very complex module and I don't see the problem and admit such.
      Hello sannag,

      Marshall's helpful debugging should have gotten you closer, at least. :-) That said, do note that XML::LibXML has lots of backward compatibility interfaces and it's fairly complex to work with. There's one small change that can help your case:

      In your buildXMLElements sub call, you're passing in the parent element directly as it is and appending child elements into it. If you pass in a ref to it instead, you can see your <CHARGE> elements appear.

      HTH. Good luck and have fun!

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1169554]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others contemplating the Monastery: (5)
As of 2024-04-18 05:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found