Perl和Xpath:考虑层次结构

Perl和Xpath:考虑层次结构,perl,xpath,xml-parsing,hierarchy,Perl,Xpath,Xml Parsing,Hierarchy,考虑到层次结构级别,我想提取XML的属性值: <?xml version="1.0" encoding="UTF-8"?> <database> <row1s> <row1 name="fox" category="mammal"> <row2s> <row2 type="1"/> <row2 type="2"/> </row2s&g

考虑到层次结构级别,我想提取XML的属性值:

<?xml version="1.0" encoding="UTF-8"?>
<database>
  <row1s>
   <row1 name="fox" category="mammal">
       <row2s>
         <row2 type="1"/>
         <row2 type="2"/>
       </row2s>
   </row1>
   <row1 name="horse" category="mammal">
       <row2s>
         <row2 type="3"/>
       </row2s>
   </row1>
   <row1 name="bee" category="insect"> 
       <row2s/>
   </row1>
   <row1 name="wasp" category="insect">
       <row2s/>
   </row1>
  </row1s>
</database>
我得到的是:

Level row1 gives: fox   
Level row2 gives: 1   
Level row2 gives: 2   
Level row2 gives: 3   
Level row1 gives: horse   
Level row2 gives: 1   
Level row2 gives: 2   
Level row2 gives: 3   
Level row1 gives: bee   
Level row2 gives: 1   
Level row2 gives: 2   
Level row2 gives: 3   
Level row1 gives: wasp   
Level row2 gives: 1   
Level row2 gives: 2   
Level row2 gives: 3   
对于每个级别1,我从级别2获取所有属性值。这不是我想要的。我只想输出对应级别1的级别2条目。但我想要的是:

Level row1 gives: fox   
Level row2 gives: 1   
Level row2 gives: 2   
Level row1 gives: horse   
Level row2 gives: 3   
Level row1 gives: bee   
Level row1 gives: wasp   
如果有任何关于如何解决这个问题的提示,我将不胜感激


谢谢。

前导的
/
表示绝对路径

my $node2 = $xp->find("//row2s/row2");
应该是

my $node2 = $xp->find("row2s/row2", $row1);

评论:

  • $node1
    $node2
    都不是节点。选择更好的名字

  • 在声明变量的地方声明变量部分违背了声明它们的目的。它们应该在适当的循环中声明


前导的
/
表示绝对路径

my $node2 = $xp->find("//row2s/row2");
应该是

my $node2 = $xp->find("row2s/row2", $row1);

评论:

  • $node1
    $node2
    都不是节点。选择更好的名字

  • 在声明变量的地方声明变量部分违背了声明它们的目的。它们应该在适当的循环中声明


以下内容修复并简化了脚本:

use strict;
use warnings;

use XML::XPath;
use XML::XPath::XMLParser;

#my $xp = XML::XPath->new( filename => "animals3.xml" );
my $xp = XML::XPath->new( ioref => \*DATA );

for my $row1 ( $xp->findnodes('//row1s/row1') ){
    printf "Level row1 gives: %s\n", $row1->getAttribute("name");

    for my $row2 ( $row1->findnodes('.//row2s/row2') ) {
        printf "Level row2 gives: %s\n", $row2->getAttribute("type");
    }
}

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<database>
  <row1s>
   <row1 name="fox" category="mammal">
       <row2s>
         <row2 type="1"/>
         <row2 type="2"/>
       </row2s>
   </row1>
   <row1 name="horse" category="mammal">
       <row2s>
         <row2 type="3"/>
       </row2s>
   </row1>
   <row1 name="bee" category="insect"> 
       <row2s/>
   </row1>
   <row1 name="wasp" category="insect">
       <row2s/>
   </row1>
  </row1s>
</database>

以下内容修复并简化了脚本:

use strict;
use warnings;

use XML::XPath;
use XML::XPath::XMLParser;

#my $xp = XML::XPath->new( filename => "animals3.xml" );
my $xp = XML::XPath->new( ioref => \*DATA );

for my $row1 ( $xp->findnodes('//row1s/row1') ){
    printf "Level row1 gives: %s\n", $row1->getAttribute("name");

    for my $row2 ( $row1->findnodes('.//row2s/row2') ) {
        printf "Level row2 gives: %s\n", $row2->getAttribute("type");
    }
}

__DATA__
<?xml version="1.0" encoding="UTF-8"?>
<database>
  <row1s>
   <row1 name="fox" category="mammal">
       <row2s>
         <row2 type="1"/>
         <row2 type="2"/>
       </row2s>
   </row1>
   <row1 name="horse" category="mammal">
       <row2s>
         <row2 type="3"/>
       </row2s>
   </row1>
   <row1 name="bee" category="insect"> 
       <row2s/>
   </row1>
   <row1 name="wasp" category="insect">
       <row2s/>
   </row1>
  </row1s>
</database>

非常感谢你的回答。我按照你的建议换了台词。输出现在只提供级别1(狐狸、马、蜜蜂、黄蜂)的属性值,而不提供相应的级别2值。如果$node1不是节点,它是什么?$element1更好吗?或者$level1?
$node1\u list
或者
$animals
是两种可能性。测试,这是因为您的XML毫无意义。尽管缩进意味着相反,但是
row1
元素都没有
row2s
子元素。我想你是想使用
你可以修复XML吗,或者你需要与现有代码兼容的代码吗?
$xrow1
$xrow2
。关于“我想知道我在哪里可以收集这些信息”,我通过阅读。就规格而言,它相当轻。不过,这可能并不适合所有人。非常感谢你的回答。我按照你的建议换了台词。输出现在只提供级别1(狐狸、马、蜜蜂、黄蜂)的属性值,而不提供相应的级别2值。如果$node1不是节点,它是什么?$element1更好吗?或者$level1?
$node1\u list
或者
$animals
是两种可能性。测试,这是因为您的XML毫无意义。尽管缩进意味着相反,但是
row1
元素都没有
row2s
子元素。我想你是想使用
你可以修复XML吗,或者你需要与现有代码兼容的代码吗?
$xrow1
$xrow2
。关于“我想知道我在哪里可以收集这些信息”,我通过阅读。就规格而言,它相当轻。不过,这可能并不适合所有人。非常感谢。我学会了一些新技巧。如果您能看看我的后续问题,我将不胜感激。很高兴能为您提供帮助。我看了一下你的新问题,但我看到博罗丁在帮助方面已经做了足够的工作。非常感谢。我学会了一些新技巧。如果您能看看我的后续问题,我将不胜感激。很高兴能为您提供帮助。我看了一下你的新问题,但我看到博罗丁在帮助方面已经做了足够的工作。