如何从有效的 XML 标记外部删除垃圾



>我有一系列从数据播放实用程序生成的XML文件。 该实用程序生成格式正确的 XML 标记。 不幸的是,该实用程序并不完美。 它尝试序列化的某些 Java 对象失败,它们只是入(作为二进制 blob)在这些其他有效的 XML 标记之间。

例如。。。

<track>
<cto>Valid_XML_HERE</cto>@Binary_Blob_of_Junk@<cto>(...)</cto>
</track>

环境是RHEL-5,这意味着Python 2.4,Perl或SED/AWK解决方案是可用的。

关于如何清除垃圾的任何建议?

我根据Birei的建议来检查树元素,但提出了一个仅SED的解决方案。 如OP所示,<cto>标签恰好在一条连续的线上。 然后,解决方案是拆分行,使每个<cto>标签都在新行上 - 因此,也将垃圾二进制数据隔离在新行上 - 然后简单地选择以<cto>标签开头的行。

<tracks></tracks>标签可以通过 CAT 简单地添加到新文件中。

以下是我测试过并确认工作的 SED 命令......

第 1 步。 隔离<cto>标记以位于新行上。

sed -i "s/<cto/n<cto/g;s/</cto>/</cto>n/g" ${FILE}

第 2 步。仅选择以 <cto> 标记开头的行。

sed -i "/<cto/p" ${FILE}

第 3 步。设置新 XML 文档的格式。

xmllint --format "${FILE}" > foo.xml

感谢您各自的所有输入。

使用 XML::Twig 解析器删除 track 标签文本的另一种方法:

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig->new(
    twig_handlers => {
        track => sub {
            for my $t ( $_->children() ) { 
                if ( $t->is_text ) { 
                    $t->set_text( '' );
                }   
            }   
        }   
    },  
    pretty_print => 'indented',
)->parsefile( shift)->print;

将文件作为第一个(也是唯一的)参数运行它:

perl script.pl xmlfile

这里有一个快速的Perl解决方案。

#!/usr/bin/perl -Tw
use strict;
use warnings;
use English qw( -no_match_vars $INPUT_RECORD_SEPARATOR );
my $text = do { local $INPUT_RECORD_SEPARATOR = undef; <>; };
my @ctos = $text =~ m{<cto>( .+? )</cto>}xmsg;
if ( @ctos ) {
    printf '<track><cto>%s</cto></track>', join '</cto><cto>', @ctos;
}
print "n";

您可以像这样通过管道传输曲目文本:

$:  cat track.txt | ./clean_track.pl 
<track><cto>Valid_XML_HERE</cto><cto>(...)</cto></track>

最新更新