使用 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 重组方式。