使用 perl 删除 xml 声明的通用解决方案
Generic solution for removing xml declararation using perl
你好,我想删除我的 xml 文件中的声明,问题是声明有时嵌入根元素。
XML 看起来如下
案例 1:
<?xml version="1.0" encoding="UTF-8"?> <document> This is a document root
<child>----</child>
</document>`
案例二:
<?xml version="1.0" encoding="UTF-8"?>
<document> This is a document root
<child>----</child>
</document>`
函数也适用于根节点在下一行的情况。
我的函数仅适用于情况 2..
sub getXMLData {
my ($xml) = @_;
my @data = ();
open(FILE,"<$xml");
while(<FILE>) {
chomp;
if(/\<\?xml\sversion/) {next;}
push(@data, $_);
}
close(FILE);
return join("\n",@data);
}
*** 请注意,编码并不总是恒定的。
好的,所以这里的问题是 - 您正在尝试基于 XML 行进行解析,但这行不通。你应该避免这样做,因为它会产生脆弱的代码,有一天会中断——正如你所注意到的——多亏了对源代码 XML 的完全有效的更改。你的两个文档在语义上是相同的,所以你的代码处理一个而不是另一个的事实就是一个例子,说明为什么这样做 XML 是一个坏主意。
但更重要的是 - 为什么要从 XML 中删除 XML 声明?你想完成什么?
一般重新格式化 XML 可以这样完成:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
pretty_print => 'indented',
);
$twig->parsefile('your_xml_file');
$twig->print;
这将解析您的 XML 并在 一种 有效格式中重新格式化 XML 。但是,我强烈建议您不要只丢弃 XML 声明,而是继续使用 XML::Twig
之类的东西来处理它。 (打开一个关于您要完成的任务的新问题,我很乐意为您提供一个不会因 XML 的不同有效格式而出错的解决方案)。
在合并 XML 文档时,XML::Twig
也可以这样做 - 并且仍然检查和验证您的 XML。
所以你可以做类似的事情(从上面扩展):
foreach my $file ( @file_list ) {
my $child = XML::Twig -> new ();
$child -> parsefile ( $xml_file );
my $child_doc = $child -> root -> cut;
$child_doc -> paste ( $twig -> root );
}
$twig -> print;
您需要做什么,在一定程度上取决于您想要的输出结构 - 无论如何,您需要在根元素中使用 'wrap'。使用一些示例输入和所需的输出打开一个新问题,我会很乐意尝试一下。
举个例子——如果你将上面的样本输入两次,你会得到:
<?xml version="1.0" encoding="UTF-8"?>
<document><document> This is a document root
<child>----</child></document> This is a document root
<child>----</child></document>
我知道这不太可能是您想要的,但希望能说明一种基于解析器的 XML 重组方式。
你好,我想删除我的 xml 文件中的声明,问题是声明有时嵌入根元素。
XML 看起来如下
案例 1:
<?xml version="1.0" encoding="UTF-8"?> <document> This is a document root
<child>----</child>
</document>`
案例二:
<?xml version="1.0" encoding="UTF-8"?>
<document> This is a document root
<child>----</child>
</document>`
函数也适用于根节点在下一行的情况。
我的函数仅适用于情况 2..
sub getXMLData {
my ($xml) = @_;
my @data = ();
open(FILE,"<$xml");
while(<FILE>) {
chomp;
if(/\<\?xml\sversion/) {next;}
push(@data, $_);
}
close(FILE);
return join("\n",@data);
}
*** 请注意,编码并不总是恒定的。
好的,所以这里的问题是 - 您正在尝试基于 XML 行进行解析,但这行不通。你应该避免这样做,因为它会产生脆弱的代码,有一天会中断——正如你所注意到的——多亏了对源代码 XML 的完全有效的更改。你的两个文档在语义上是相同的,所以你的代码处理一个而不是另一个的事实就是一个例子,说明为什么这样做 XML 是一个坏主意。
但更重要的是 - 为什么要从 XML 中删除 XML 声明?你想完成什么?
一般重新格式化 XML 可以这样完成:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
pretty_print => 'indented',
);
$twig->parsefile('your_xml_file');
$twig->print;
这将解析您的 XML 并在 一种 有效格式中重新格式化 XML 。但是,我强烈建议您不要只丢弃 XML 声明,而是继续使用 XML::Twig
之类的东西来处理它。 (打开一个关于您要完成的任务的新问题,我很乐意为您提供一个不会因 XML 的不同有效格式而出错的解决方案)。
在合并 XML 文档时,XML::Twig
也可以这样做 - 并且仍然检查和验证您的 XML。
所以你可以做类似的事情(从上面扩展):
foreach my $file ( @file_list ) {
my $child = XML::Twig -> new ();
$child -> parsefile ( $xml_file );
my $child_doc = $child -> root -> cut;
$child_doc -> paste ( $twig -> root );
}
$twig -> print;
您需要做什么,在一定程度上取决于您想要的输出结构 - 无论如何,您需要在根元素中使用 'wrap'。使用一些示例输入和所需的输出打开一个新问题,我会很乐意尝试一下。
举个例子——如果你将上面的样本输入两次,你会得到:
<?xml version="1.0" encoding="UTF-8"?>
<document><document> This is a document root
<child>----</child></document> This is a document root
<child>----</child></document>
我知道这不太可能是您想要的,但希望能说明一种基于解析器的 XML 重组方式。