How can I write XML data to a file with Perl?
Could you please correct my code below.
#!/usr/local/bin/perl
open (MYFILE, '>>data.xml');
print MYFILE "<?xml version="1.0" encoding="UTF-8"开发者_运维百科?>\n";
close (MYFILE);
Updated.
#!/usr/local/bin/perl
open (MYFILE, '>>data.xml');
print MYFILE '<?xml version="1.0" encoding="UTF-8"?\>'."\n";
print MYFILE '<?xml version="1.0" encoding="UTF-16"?\>'."\n";
close (MYFILE);
output: working well now.
<?xml version="1.0" encoding="UTF-8"?\>
<?xml version="1.0" encoding="UTF-16"?\>
BUT.
#!/usr/local/bin/perl
open (MYFILE, '>>data.xml');
print MYFILE '<?xml version="1.0" encoding="UTF-8"?\>'.'\n';
print MYFILE '<?xml version="1.0" encoding="UTF-16"?\>'.'\n';
close (MYFILE);
Output: # error format with \n
<?xml version="1.0" encoding="UTF-8"?\>\n<?xml version="1.0" encoding="UTF-16"?\>\n
The problem is you have unescaped quotes in the string. Either escape the quotes using the backslash or surround your print string with qq{}:
print MYFILE qq{<?xml version="1.0" encoding="UTF-8"?>\n};
--or--
print MYFILE "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
print MYFILE qq{<?xml version="1.0" encoding="UTF-8"?>\n};
Your problem is that you had nested double quotes; using qq{}
to delimit the string will solve this issue.
Always turn on warnings and strictures, so you find out earlier what went wrong, and get more details why:
#!/usr/local/bin/perl
use strict;
use warnings;
Always use the lexical-variabled, three-argument form of open
(there's a big discussion why over here), and always check the return value (it will return an error if something went wrong, and put the reason why in the $!
variable (see under $!
at perldoc perlvar). Also, die
will print the line number of where the program quit if you don't end your string with a \n
(more at perldoc -f die).
open my $file, '>>', 'data.xml' or die "Can't open file: $!";
And use double-quotes around the \n
so that it is printed properly:
print $file '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
print $file '<?xml version="1.0" encoding="UTF-16"?>' . "\n";
close $file;
I would recommend to use:
use XML::Simple;
Here is some code of mine for printing an XML file:
open(XML, ">$xmlfile");
print XML (<<EOF);
<?xml version="1.0" encoding="UTF-8"?>
<gpx
version="1.1"
creator="Navaid Waypoint Generator - http://navaid.com/GPX/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.topografix.com/GPX/1/1"
xmlns:navaid="http://navaid.com/GPX/NAVAID/1/0"
xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd
http://navaid.com/GPX/NAVAID/1/0 http://navaid.com/GPX/NAVAID/1/0">
<metadata>
<author>
<name>Paul Tomblin</name>
<email id="ptomblin" domain="xcski.com"/>
<link href="http://blog.xcski.com/"/>
</author>
<link href="http://navaid.com/GPX/"/>
</metadata>
EOF
Always, always, ALWAYS check the value returned from open
, e.g.,
open (MYFILE, '>>data.xml')
or die "$0: open: $!";
Note the important bits in the error message:
- the name of the program that failed,
$0
- what it was trying to do,
open
- why it failed,
$!
Without a newline at the end of the string passed to die
, it appends the file and line number where your program died.
If you want to write UTF-8 data to a file (as you say in your XML declaration, open the file with a UTF-8 encoding:
open my($fh), '>:utf8', 'data.xml' or die "Could not open file: $!";
print $fh qq{<?xml version="1.0" encoding="UTF-8">\n};
Several additional points of advice:
For writing complex, structured files, use a library like XML::Simple or one of the many, many others available on CPAN.
If you are writing many very similar files, a templating module may be more appropriate.
Take Ether's advice re:
open
,strict
andwarnings
. It will save you time debugging.If you are going to claim that a file has a particular encoding (UTF-8 or UTF-16), you probably should emit actual Unicode text to the file. There is more info in perldoc -f open.
精彩评论