【问题标题】:read XML from and to file while preserving format在保留格式的同时从文件中读取 XML
【发布时间】:2016-11-03 23:09:01
【问题描述】:

我使用这个 perl 代码从一个文件中读取 XML,然后写入另一个文件(我的完整脚本包含添加属性的代码):

#!usr/bin/perl -w

use strict;
use XML::DOM;
use XML::Simple;

my $num_args = $#ARGV + 1;

if ($num_args != 2) {
  print "\nUsage: ModifyXML.pl inputXML outputXML\n";
  exit;
}

my $inputPath = $ARGV[0];
my $outputPath = $ARGV[1];

open(inputXML, "$inputPath") || die "Cannot open $inputPath \n";

my $parser = XML::DOM::Parser->new();
my $data = $parser->parsefile($inputPath) || die "Error parsing XML File";

open my $fh, '>:utf8', "$outputPath" or die "Can't open $outputPath for writing: $!\n";
$data->printToFileHandle($fh);

close(inputXML);

但是,这不会保留换行符等字符。例如,这个 XML:

<?xml version="1.0" encoding="utf-8"?>
<Test>
    <Notification Content="test1     testx &#xD;&#xA;test2&#xD;&#xA;test3&#xD;&#xA;" Type="Test1234">
    </Notification>
</Test>

变成这样:

<?xml version="1.0" encoding="utf-8"?>
<Test>
    <Notification Content="test1     testx 

test2

test3

" Type="Test1234">
    </Notification>
</Test>

我怀疑我没有正确写入文件。

【问题讨论】:

  • 当我想到“保留换行符”时,这根本不是我想到的。在这里,您希望保留恰好代表 CR/LF 字符的 编码
  • 看起来 XML::DOM 设置了一个默认处理程序来扩展所有内容(参见 DOM.pm 第 2054-58 行)。您是否尝试过摆弄它以获得您想要的 noexpand 行为?
  • XML::DOM 的那部分似乎不太正常 - 不过感谢您的建议

标签: xml perl parsing format


【解决方案1】:

例如,使用XML::LibXML。参与的主要模块是XML::LibXML::ParserXML::LibXML::DOM(以及其他模块)。返回的对象一般为XML::LibXML::Document

use warnings 'all';
use strict;

use XML::LibXML;

my $inputPath  = 'with_encodings.xml';
my $outputPath = 'keep_encodings.xml';

my $reader = XML::LibXML->new();
my $doc = $reader->load_xml(location => $inputPath, no_blanks => 1); 

print $doc->toString();

my $state = $doc->toFile($outputPath);

我们不必先创建一个对象,直接说XML::LibXML-&gt;load_xml即可。我这样做是因为这样可以在解析之前但在构造函数之外使用$reader 上的方法来设置编码(例如)。

这个模块也更方便处理。

XML::Twig 也应该保留编码,并且更适合处理。

【讨论】:

    【解决方案2】:

    仅供参考,我可以通过切换到不同的 XML 解析器来做到这一点。现在使用 XML::LibXML。

    语法类似,除了它是 'parse_file' 而不是 'parsefile',而且你使用带有文件名的 'toFile' 而不是 'printToFileHandle'。

    【讨论】:

    • 您可以在 zdim 的答案上发表评论或编辑答案以改进。
    • 从“已回答”时间戳可以看出,此答案早于 zdim 的答案。
    • 哦,抱歉。 (如果想知道,这不是我的反对意见,只是以防万一)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多