【问题标题】:Perl : Handling duplicate element names using XML::SAXPerl:使用 XML::SAX 处理重复的元素名称
【发布时间】:2012-01-09 03:46:25
【问题描述】:

如何处理 perl XML::SAX 模块中重复的元素名称?以下是我的 xml 文件:

<employees>
    <employee>
        <name>John</name>
        <age>gg</age>
        <department>Operations</department>
        <amount Ccy="EUR">100</amount>
        <company>
            <name> abc </name>
        </company>
    </employee>
    <employee>
        <name>Larry</name>
        <age>45</age>
        <department>Accounts</department>
        <amount Ccy="EUR">200</amount>
        <company>
            <name> xyz </name>
        </company>
    </employee>
</employees>

我的问题是如何访问元素employees->employee->company->name? (我应该能够打印“abc”和“xyz”)。我问这个的原因是因为在employees->employee->name 处还有一个我想跳过的“name”元素。我只想使用 XML::SAX,因为我的环境只支持这个模块。请帮忙。非常感谢。

【问题讨论】:

    标签: perl


    【解决方案1】:

    使用堆栈记录您所在的节点,每次进入节点时pushing,每次离开节点时poping:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Data::Dumper;
    use XML::SAX::ParserFactory;
    use XML::SAX::PurePerl;
    
    my (@nodes, $characters, @names);
    
    my $factory = new XML::SAX::ParserFactory;
    my $handler = new XML::SAX::PurePerl;
    my $parser = $factory->parser(
                      Handler => $handler,
                      Methods => {
                      start_element => sub {
                          push @nodes, shift->{LocalName};
                      },
                      characters => sub {
                          $characters = shift->{Data};
                      },
                      end_element => sub {
                          if (shift->{LocalName} eq 'name' && $nodes[-2] eq 'company') {
                              push @names, $characters;
                          }
                          pop @nodes;
                      }
                  }
                  );
    $parser->parse_uri("sample2.xml");
    
    print Dumper \@names;
    

    输出:

    $VAR1 = [
              ' abc ',
              ' xyz '
            ];
    

    $nodes[-2]@nodes 中倒数第二个元素,当shift-&gt;{LocalName} 等于“姓名”时将解析为“员工”或“公司”

    【讨论】:

    • 切换到XML::LibXMLXML::Twig 会将代码减少到大约三行。这正是不适合 SAX 的工作类型 :-)
    • @choroba:假设他的 xml 文件不是很大,而且内存很重要,那是真的。在他的问题中,他说这是他唯一可用的模块。据我所知,XML::SAX 的使用示例也很有限,因此只要表明最好避免使用它,就值得付出努力。 ;) 我和下一个(Perl)人一样喜欢简洁的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-17
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    相关资源
    最近更新 更多