使用 XML::Twig 导航 XML 文件
Navigating XML file using XML::Twig
我必须说我是 Perl 的新手,XML:Twig 但我学得很快。您可以提供的任何帮助将不胜感激。
基本上,我在导航到 XML 文件中的某些节点以便提取信息时遇到问题。
我正在使用 TwigHandler 来访问 XML 中的某个节点,特别是 "Selection" 节点。 TwigHandler 对我来说工作得很好,因为我能够在这个级别提取我需要的一些信息。但是,我需要检查 "Selection" 下的其他节点,但我不知道如何访问它们。
我在下面复制了我的 XML 的片段,以便您可以看到它的样子。在其中您可以看到选择节点。我可以使用我的 Twig 处理程序毫无问题地访问属性 "id" 和字段 "Name",但是我需要遍历 Selection 节点下的所有这些 "Message" 节点,以便从每个属性中提取所有属性。我试图让 "get_xpath" 工作但无济于事。
请记住,在我的 XML 中,每个选择节点下都有消息节点。您在下面的示例中只看到 2 个选择节点,但实际上我可以有数百个 "Selection" 节点,每个节点都有 "Message" 个节点作为子节点。我需要从我正在使用的当前 "Selection" 节点下的 "Message" 节点中提取信息,即,我不关心可能位于不同 "Message" 下的其他 "Message" 节点 "Selection"节点。
<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>
在 Selection
的处理程序中使用 findnodes()
和相对 XPath 来查找 Contents/Message
子节点:
#!/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>
测试运行:
$ 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
我必须说我是 Perl 的新手,XML:Twig 但我学得很快。您可以提供的任何帮助将不胜感激。
基本上,我在导航到 XML 文件中的某些节点以便提取信息时遇到问题。
我正在使用 TwigHandler 来访问 XML 中的某个节点,特别是 "Selection" 节点。 TwigHandler 对我来说工作得很好,因为我能够在这个级别提取我需要的一些信息。但是,我需要检查 "Selection" 下的其他节点,但我不知道如何访问它们。
我在下面复制了我的 XML 的片段,以便您可以看到它的样子。在其中您可以看到选择节点。我可以使用我的 Twig 处理程序毫无问题地访问属性 "id" 和字段 "Name",但是我需要遍历 Selection 节点下的所有这些 "Message" 节点,以便从每个属性中提取所有属性。我试图让 "get_xpath" 工作但无济于事。
请记住,在我的 XML 中,每个选择节点下都有消息节点。您在下面的示例中只看到 2 个选择节点,但实际上我可以有数百个 "Selection" 节点,每个节点都有 "Message" 个节点作为子节点。我需要从我正在使用的当前 "Selection" 节点下的 "Message" 节点中提取信息,即,我不关心可能位于不同 "Message" 下的其他 "Message" 节点 "Selection"节点。
<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>
在 Selection
的处理程序中使用 findnodes()
和相对 XPath 来查找 Contents/Message
子节点:
#!/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>
测试运行:
$ 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