Perl和Xpath:考虑层次结构
考虑到层次结构级别,我想提取XML的属性值: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 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
。关于“我想知道我在哪里可以收集这些信息”,我通过阅读。就规格而言,它相当轻。不过,这可能并不适合所有人。非常感谢。我学会了一些新技巧。如果您能看看我的后续问题,我将不胜感激。很高兴能为您提供帮助。我看了一下你的新问题,但我看到博罗丁在帮助方面已经做了足够的工作。非常感谢。我学会了一些新技巧。如果您能看看我的后续问题,我将不胜感激。很高兴能为您提供帮助。我看了一下你的新问题,但我看到博罗丁在帮助方面已经做了足够的工作。