使用XML::TWIG导航XML以访问CDATA

使用XML::TWIG导航XML以访问CDATA,xml,perl,xml-twig,Xml,Perl,Xml Twig,我有这个XML文件,我需要一次访问一个特定的节点。下面是我的XML示例以及示例代码 我的代码运行良好,只是我循环了所有消息/内容标记,而不是在当前消息标记下获取特定的消息/内容标记。例如,当处理当前消息标记时,我将返回3个消息/内容标记(带有refid=“123991123”)而我只希望返回1()。希望这是有意义的。这里的任何帮助都将不胜感激 代码: XML: 主人 一些英文内容]> 一些法语内容]> 人民币 美国残疾人协会]> 以下是第一次尝试,尝试了解基于XML结构的代码应该做什么: 选

我有这个XML文件,我需要一次访问一个特定的节点。下面是我的XML示例以及示例代码

我的代码运行良好,只是我循环了所有消息/内容标记,而不是在当前消息标记下获取特定的消息/内容标记。例如,当处理当前消息标记时,我将返回3个消息/内容标记(带有refid=“123991123”)而我只希望返回1()。希望这是有意义的。这里的任何帮助都将不胜感激

代码:

XML:


主人
一些英文内容

]> 一些法语内容

]> 人民币 美国残疾人协会

]>
以下是第一次尝试,尝试了解基于XML结构的代码应该做什么:

  • 选择
    节点的处理程序在
    内容
    节点下的
    消息
    节点下查找属性为
    语言=='en'
    的子
    内容
    节点
    • 转换为XPath
      /Contents/Message/Content[@language='en']
    • 如果它有一个属性
      imagelibraryid
      ,则存储该属性的值
    • 否则,存储第一个子项的
      CDATA
      内容
    • refid
      设置为来自父
      消息
      节点的属性值
  • 将它们附加到
    选择
    节点的内容列表中
  • 要显示收集的内容,请在数组ref上使用
#/usr/bin/perl
使用警告;
严格使用;
使用XML::Twig;
使用数据::转储程序;
我的%选择;
my$twig=XML::twig->new(
细枝处理程序=>{
选择=>sub{
#$\->print();
打印“选择id:,$\->att('id'),“\n”;
我的@内容;
foreach my$content($\->findnodes(“./Contents/Message/content[\@language='en'])){
我的$result={
refid=>$content->parent->att('refid'),
};
my$id=$content->att('imagelibraryid');
if(定义为$id){
$result->{library}=$id;
}否则{
$result->{cata}=$content->first\u child->cdata;
}
推送(@contents$result);
}
#将收集的内容节点存储在选择ID下
$selections{$\->att('id')}=\@contents;
},
}
);
$twig->parse(\*数据);
while(我的($id,$contents)=每个%selections){
my$dump=转储程序($contents);
打印“选择“${id}”消息:$dump\n”;
}
出口0;
__资料__
... 剩下的XML被遗漏了。。。
试运行:

$perl dummy.pl
选择id:54008473
选择id:54008475
选择“54008473”消息:$VAR1=[
{
“refid”=>“123991123”,
“库”=>“5492396”
},
{
“cata”=>“一些英文内容

”, “refid”=>“128054778” } ]; 选择“54008475”消息:$VAR1=[ { “cata”=>“ada

”, “refid”=>“128054778” } ];
您的代码不会在严格/警告下编译,并且从未设置
$Message\u refid
。请修复此问题,以便对其进行调试。我很难理解您试图使代码执行的操作。您试图获得什么输出?使用
CDATA
指令更新答案。我希望这就是你们想要的。大家好,很抱歉我的问题不清楚。可悲的是…我以为这很清楚。我以后会尽量讲清楚的。话虽如此,斯蒂芬,我想你是唯一懂我语言的人:)。不知道这是好消息还是坏消息。不管怎样,你的代码几乎准确无误。我添加的唯一内容是[\@refid='$Message\u refid'],以仅隔离特定消息节点下的内容项(请参见下面的代码):foreach my$Content($\->findnodes(“./Contents/Message[\@refid=''$Message\u refid']]/Content[\@language='en']){谢谢!我从你那里学到了很多东西。Angelo
my $twig = XML::Twig->new(
twig_handlers => {
    Selection => sub {
        foreach my $message ($_->findnodes('./Contents/Message')) {

            if($message->att('custom')){
                $Message_custom = $message->att('custom');
                foreach my $Content ($_->findnodes('./Contents/Message/Content')) {
                    print $Selection_id.": ".$Message_refid.": ".$TotalContents++."\n";
                    if($Content->att('language') eq "en"){
                        if($Content->att('imagelibraryid')){
                            $Message_Content_language_en_imagelibraryid = $Content->att('imagelibraryid');
                        }else{
                            $Message_Content_language_en = substr($message->field('Content'), 0, 20);
                        }
                    }
                }
            }
        }
    },
}
);
<?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">
        <Content language="en" imagelibraryid="5492396"/>
      </Message>
      <Message refid="128054778" custom="true" status="New">
        <Content language="en"><![CDATA[<p>Some English content</p>]]></Content>
        <Content language="fr"><![CDATA[<p>Some French content</p>]]></Content>
      </Message>
    </Contents>
  </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>
  </Selection>
</Root>