首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用XML::Twig导航XML文件

使用XML::Twig导航XML文件
EN

Stack Overflow用户
提问于 2019-03-13 16:10:02
回答 1查看 149关注 0票数 0

我必须说,我是Perl和XML:Twig的新手,但我学得很快。如果您能提供任何帮助,我们将不胜感激。

基本上,我在导航到XML文件中的某些节点以便提取信息时遇到了问题。

我使用TwigHandler来访问XML中的某个节点,特别是"Selection“节点。从某种意义上说,TwigHandler对我来说工作得很好,因为我能够在这个级别提取一些我需要的信息。但是,在"Selection“下有一些额外的节点需要检查,但我不知道如何访问它们。

我已经复制了下面的XML片段,这样您就可以看到它是什么样子了。在其中您可以看到选择节点。我可以使用我的Twig Handler毫无问题地访问属性"id“和字段"Name”,但我需要遍历Selection节点下的所有"Message“节点,以便从每个节点中提取所有属性。我尝试过让"get_xpath“正常工作,但是没有效果。

请记住,在我的XML中,每个选择节点下都有消息节点。在下面的示例中,您只看到2个选择节点,但实际上我可以有数百个“选择”节点,每个节点都有"Message“节点作为子节点。我需要从我正在处理的当前“选择”节点下的“消息”节点中提取信息,也就是说,我不关心可能在不同“选择”节点下的其他“消息”节点。

代码语言:javascript
复制
<Selection id="54008473">
  <Name>Master</Name>
  <Contents>
    <Message refid="125796458" suppress="true" status="Unchanged"/>
    <Message refid="123991123" suppress="true" status="Unchanged"/>
    <Message refid="128054778" custom="true" status="New">
      <Content language="en"><![CDATA[<p>ada</p>]]></Content>
    </Message>
  </Contents>
  <Messages/>
  <MessagePriority>
    <Zone name="Insured Letter Intro">
      <MessageInstance id="125796375" name="LD Letter Introduction" status="Active" delivery="Mandatory" priority="1" suppressed="false" selected="true"/>
    </Zone>
    <Zone name="Insured Letter Logo">
      <MessageInstance id="125794623" name="Insured Letter Logo" status="Active" delivery="Mandatory" priority="1" suppressed="false" selected="true"/>
     </Zone>
  </MessagePriority>
</Selection>
<Selection id="54008475" datavaluerefid="54008479">
  <Name>RMBC</Name>
  <Contents>
    <Message refid="125796458" sameasparent="true" parentrefid="54008473" status="Unchanged"/>
    <Message refid="123991123" sameasparent="true" parentrefid="54008473" status="Unchanged"/>
    <Message refid="128054778" custom="true" status="New">
      <Content language="en"><![CDATA[<p>ada</p>]]></Content>
    </Message>
  </Contents>
  <Messages/>
  <MessagePriority>
     ...
  </MessagePriority>
</Selection>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-03-13 18:55:25

Selection的处理程序中使用带有相对XPath的findnodes()来查找Contents/Message子节点:

代码语言:javascript
复制
#!/usr/bin/perl
use warnings;
use strict;

use XML::Twig;

my %selections;

my $twig = XML::Twig->new(
    twig_handlers => {
        Selection => sub {
            #$_->print();
            print "selection id: ", $_->att('id'), "\n";

            my @messages;
            foreach my $message ($_->findnodes('./Contents/Message')) {
                #$message->print();
                print "message refid: ", $message->att('refid'), "\n";

                # store "refid" attribute in messages list
                push(@messages, $message->att('refid'));
            }

            # store collected Message nodes under selection ID
            $selections{ $_->att('id') } = \@messages;
        },
    }
);

$twig->parse(\*DATA);

while (my($id, $messages) = each %selections) {
    print "Selection '${id}' messages: @{ $messages }\n";
}

exit 0;

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<Root>
  <Selection id="54008473">
    <Name>Master</Name>
    <Contents>
      <Message refid="125796458" suppress="true" status="Unchanged"/>
      <Message refid="123991123" suppress="true" status="Unchanged"/>
      <Message refid="128054778" custom="true" status="New">
        <Content language="en"><![CDATA[<p>ada</p>]]></Content>
      </Message>
    </Contents>
    <Messages/>
    <MessagePriority>
      <Zone name="Insured Letter Intro">
        <MessageInstance id="125796375" name="LD Letter Introduction" status="Active" delivery="Mandatory" priority="1" suppressed="false" selected="true"/>
      </Zone>
      <Zone name="Insured Letter Logo">
        <MessageInstance id="125794623" name="Insured Letter Logo" status="Active" delivery="Mandatory" priority="1" suppressed="false" selected="true"/>
      </Zone>
    </MessagePriority>
  </Selection>
  <Selection id="54008475" datavaluerefid="54008479">
    <Name>RMBC</Name>
    <Contents>
      <Message refid="125796458" sameasparent="true" parentrefid="54008473" status="Unchanged"/>
      <Message refid="123991123" sameasparent="true" parentrefid="54008473" status="Unchanged"/>
      <Message refid="128054778" custom="true" status="New">
        <Content language="en"><![CDATA[<p>ada</p>]]></Content>
      </Message>
    </Contents>
    <Messages/>
    <MessagePriority>
      ...
    </MessagePriority>
  </Selection>
</Root>

测试运行:

代码语言:javascript
复制
$ perl dummy.pl
selection id: 54008473
message refid: 125796458
message refid: 123991123
message refid: 128054778
selection id: 54008475
message refid: 125796458
message refid: 123991123
message refid: 128054778
Selection '54008473' messages: 125796458 123991123 128054778
Selection '54008475' messages: 125796458 123991123 128054778
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55137061

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档