我有一个问题,需要一些帮助。首先,要温柔。我对perl和LibXML都是新手。
我一直在分析一个文档,并将元素放入一个数组中,然后将其写入电子表格列。在测试过程中,发现一些节点有多个子节点同名。我需要将每个子节点的文本组合到数组的一个元素中。
xml的(非常简化的)格式是:
<Group>
<title>
<description>
<reference>
<fixtext>
<check>
<check-content> "Some text I want to pull"
但偶尔它是这样的:
<Group>
<title>
<description>
<reference>
<fixtext>
<check>
<check-content> "Some text I want to pull"
<check-content> "Some more text I want to pull and join to the first"
我可以提取<check>
以下的所有内容,但不能从该变量中提取<check-content>
。
我一直在做的是:
my @Check_Content;
my $Check_Content;
my $parser = XML::LibXML->new() or die $!;
my $doc1 = $parser->parse_file($filename1);
my $xc1 = XML::LibXML::XPathContext->new($doc1->documentElement() );
$xc1->registerNs(x => 'http://checklists.nist.gov/xccdf/1.1');
for my $Check ( $xc1->findnodes('//x:Group/x:Rule/x:check') ) {
print "This is Check $Checkn";
my $result_string;
for my $Check_Content ( $Check->findvalue('check-content') ) {
print "This is Check Content $Check_Contentn";
$result_string .= $Check_Content->to_literal;
}
push (@Check_Content, $result_string);
}
第一个print语句证明<check>
以下的所有内容都被拉取。但是,第二个print语句始终为空。就好像它不再是XML格式,并且无法拉取节点。
我已经使用了我能想到的("检查内容")的每一个变量,即
('/check-content')
('//check-content')
('/x:check-content')
('//check-content')
('//x:check-content')
我可能错过了一个,但我不这么认为。
如有任何帮助,我们将不胜感激。
在发布未来问题时,首先要记住几点:
- 您没有提供一个易于使用的测试用例。特别是:
- 您的XML文档不完整且格式不正确
- 您提供的XPath查询甚至与您提供的XML片段不匹配
- 您在XML中省略了名称空间标记
- 您没有阅读perl给您的错误消息
因此,这里有一个适用于您的用例的有效XML文档:
<x:Group xmlns:x="http://checklists.nist.gov/xccdf/1.1">
<x:title>
<x:description>
<x:reference>
<x:fixtext>
<x:check>
<x:check-content> "Some text I want to pull"</x:check-content>
<x:check-content> "Some more text I want to pull and join to the first"</x:check-content>
</x:check>
</x:fixtext>
</x:reference>
</x:description>
</x:title>
</x:Group>
这里有一个(除了顶部的初始解析代码外,几乎已经完成)脚本来处理XML:
my @Check_Content;
my $Check_Content;
my $xc1 = XML::LibXML::XPathContext->new($doc1->documentElement() );
$xc1->registerNs(x => 'http://checklists.nist.gov/xccdf/1.1');
for my $Check ( $xc1->findnodes('//x:Group//x:check') ) {
print "This is Check $Checkn";
my $result_string;
for my $Check_Content ( $Check->findvalue('x:check-content') ) {
print "This is Check Content $Check_Contentn";
$result_string .= $Check_Content->to_literal;
}
push (@Check_Content, $result_string);
}
当我在这个XML上运行这个脚本时,我得到的输出是:
This is Check <x:check>
<x:check-content> "Some text I want to pull"</x:check-content>
<x:check-content> "Some more text I want to pull and join to the first"</x:check-content>
</x:check>
This is Check Content "Some text I want to pull" "Some more text I want to pull and join to the first"
Can't locate object method "to_literal" via package " "Some text I want to pull" "Some more text I want to pull and join to the first"" (perhaps you forgot to load " "Some text I want to pull" "Some more text I want to pull and join to the first""?) at ./hm.pl line 27, <DATA> line 15.
因此,两个问题立即出现:
- 两个节点都被提取为一个结果
findcontent()
返回一个字符串;你不能打给to_literal()
所以要解决这个问题:
- 将您的
findcontent()
呼叫更改为findnodes()
呼叫 - 鲍勃是你的叔叔
祝你好运!