如何使用 Perl 的 XML::Twig 解析不完整的 XML 片段?

发布于 2024-09-26 07:48:49 字数 234 浏览 7 评论 0原文

我正在尝试从 XML 格式的日志文件中提取数据。由于这些数据很大,我使用 XML::Twig 从 由于这些是来自 STDIN 的串联数据,因此 XML 的格式远非

良好。解析器经常因错误而停止。如何让 XML 解析器忽略错误并仅提取我感兴趣的标签?我是否必须退回到正则表达式解析(开始标记 - 结束标记)?

I'm trying to extract data from log files in XML format. As these are huge, I am using XML::Twig to extract the relevant data from a buffer instead of the whole file(s)

As these are concatenaded data from STDIN, the XML is far from well formed. So frequently the parser stops with an error. How can I get the XML parser to ignore the errors and only extract the tags I am interested in? Do I have to fall back to regular expression parsing (start-tag - end-tag)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

美羊羊 2024-10-03 07:48:49

实际上,我只是累积 标记之间的数据,然后解析该字符串,假设每条消息的内容都很小:

#!/usr/bin/perl

use strict; use warnings;

use XML::Simple;
use Data::Dumper;

my $in_message;
my $message;

LOGENTRY:
while ( my $line = <DATA> ) {
    while ( $line =~ /^<message/ .. $line =~ m{</message>$} ) {
        $message .= $line;
        next LOGENTRY;
    }
    if ( $message ) {
        process_message($message);
        $message = '';
    }
}

sub process_message {
    my ($message) = @_;

    my $xml = XMLin(
        $message,
        ForceArray => 1,
    );
    print Dumper $xml;
}

__DATA__
ldksj
lskdfj
lksd

sdfk

<message sender="1">Hi</message>

sdk
dkj

<message sender="2">Hi yourself!</message>

sd

输出:

$VAR1 = {
          'sender' => '1',
          'content' => 'Hi'
        };
$VAR1 = {
          'sender' => '2',
          'content' => 'Hi yourself!'
        };

I would actually just accumulate the data between <message></message> tags and then parse that string, assuming the content of each message is small:

#!/usr/bin/perl

use strict; use warnings;

use XML::Simple;
use Data::Dumper;

my $in_message;
my $message;

LOGENTRY:
while ( my $line = <DATA> ) {
    while ( $line =~ /^<message/ .. $line =~ m{</message>$} ) {
        $message .= $line;
        next LOGENTRY;
    }
    if ( $message ) {
        process_message($message);
        $message = '';
    }
}

sub process_message {
    my ($message) = @_;

    my $xml = XMLin(
        $message,
        ForceArray => 1,
    );
    print Dumper $xml;
}

__DATA__
ldksj
lskdfj
lksd

sdfk

<message sender="1">Hi</message>

sdk
dkj

<message sender="2">Hi yourself!</message>

sd

Output:

$VAR1 = {
          'sender' => '1',
          'content' => 'Hi'
        };
$VAR1 = {
          'sender' => '2',
          'content' => 'Hi yourself!'
        };
不如归去 2024-10-03 07:48:49

我最终得到了一个双重解决方案,其中我编写了一个简单的解析器例程,可以提取多行 元素,并将这些格式良好的片段通过管道传输到另一个例程,在该例程中我使用 Perl XML 库来提取数据。

I ended up with a dual solution where I wrote a simple parser routine that could extract multiline <message> elements, and piped these well-formed fragments to another routine where I used Perl XML libraries to extract data.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文