【问题标题】:How can I parse incomplete XML fragments with Perl's XML::Twig?如何使用 Perl 的 XML::Twig 解析不完整的 XML 片段?
【发布时间】:2011-04-22 20:43:45
【问题描述】:

我正在尝试从 XML 格式的日志文件中提取数据。由于这些都很大,我使用XML::Twig 从缓冲区而不是整个文件中提取相关数据

由于这些是来自 STDIN 的级联数据,因此 XML 的格式还很不完善。解析器经常因错误而停止。如何让 XML 解析器忽略错误并仅提取我感兴趣的标签?我是否必须退回到正则表达式解析(开始标签 - 结束标签)?

【问题讨论】:

  • 您能否提供一个示例,说明您将什么连接到来自 STDIN 的日志?还有你在找什么标签?
  • 这些是 openfire/jabber/xmpp 日志。相关数据(聊天记录)在 标签之间

标签: xml perl parsing xml-twig


【解决方案1】:

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

【讨论】:

    【解决方案2】:

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

    #!/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 = {
              '发件人' => '1',
              '内容' => '嗨'
            };
    $VAR1 = {
              '发件人' => '2',
              '内容' => '你好!
            };

    【讨论】:

    • 感谢(非常优雅!)解决方案建议。但是我担心每个 标签不会在一行,一个新的 可以在同一行开始等等。这使得它(稍微)更难以解析!我希望 Xml:Twig 能让我免于进行设置、维护缓冲区等工作
    猜你喜欢
    • 2011-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-08
    • 1970-01-01
    相关资源
    最近更新 更多