如果solve
为user
,则需要name
(LINES
)的值。
如果solve
为imm
且名称为ARCH
,则需要value
(6M
)的值
我尝试了以下内容:
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file(...);
my $j = 0;
my @imm;
$imm[$j++] = $_->data
foreach
$doc->findnodes(
"//meters/meter"
."/name[../value[\@solve/string() = 'immediate']]"
."/text()");
错误是
Possible unintended interpolation of @solve in string
Global symbol "@solve" requires explicit package name
示例XML:
<rules>
<meters>
<meter>
<name>LINES</spirit:name>
<display>LINES</display>
<description>Specifies the number of lines</description>
<value
solve="user"
id="LINES"
order="11"
format="long"
dataType="integer"
min="2"
max="34">34</value>
</meter>
<meter>
<name>ARCH</name>
<display>Define ARCH</display>
<description>Define ARCH</description>
<value
format="string"
solve="imm"
id="ARCH"
>6M</value>
</meter>
</meters>
</rules>
<rules>
<meters>
<meter>
<name>LINES</spirit:name>
<display>LINES</display>
<description>Specifies the number of lines</description>
<value
solve="user"
id="LINES"
order="11"
format="long"
dataType="integer"
min="2"
max="34">34</value>
</meter>
<meter>
<name>ARCH</name>
<display>Define ARCH</display>
<description>Define ARCH</description>
<value
format="string"
solve="imm"
id="ARCH"
>6M</value>
</meter>
</meters>
</rules>
答案 0 :(得分:1)
快速而肮脏的黑客来解决您的问题 - 使用XML::Simple
:
use strict;
use warnings;
use XML::Simple ;
use Data::Dumper;
my $xml = XMLin(qq|
<xml>
<rules>
<meters>
<meter>
<name>LINES</name>
<display>LINES</display>
<description>Specifies the number of lines</description>
<value
solve="user"
id="LINES"
order="11"
format="long"
dataType="integer"
min="2"
max="34">34</value>
</meter>
<meter>
<name>ARCH</name>
<display>Define ARCH</display>
<description>Define ARCH</description>
<value
format="string"
solve="imm"
id="ARCH"
>6M</value>
</meter>
</meters>
</rules>
<rules>
<meters>
<meter>
<name>LINES</name>
<display>LINES</display>
<description>Specifies the number of lines</description>
<value
solve="user"
id="LINES"
order="11"
format="long"
dataType="integer"
min="2"
max="34">34</value>
</meter>
<meter>
<name>ARCH</name>
<display>Define ARCH</display>
<description>Define ARCH</description>
<value
format="string"
solve="imm"
id="ARCH"
>6M</value>
</meter>
</meters>
</rules>
</xml>|,
ForceArray => 1);
foreach my $rule( @{ $xml->{rules} } ){
foreach my $meter ( @{ $rule->{meters} } ){
foreach my $m ( @{ $meter->{meter} } ){
if ( $m->{value}->{LINES} and $m->{value}->{LINES}->{solve} eq 'user' ) {
print "user solver: ".$m->{name}->[0]."\n";
} elsif ( $m->{value}->{ARCH}->{solve} and $m->{name}->[0] and $m->{value}->{ARCH}->{solve} eq 'imm' and $m->{name}->[0] eq 'ARCH' ) {
print "imm solver: ".Dumper( $m->{value}->{ARCH}->{content})."\n";
} else {
print "no solver???".Dumper($m);
}
}
}
}
我希望你能以此为出发点。
<强>观察强>
foreach
es只包含一条指令(if
),它们可以重写为maps
,但我不鼓励if
也可以使用ternary operator
和print
结果字符串重写map
和2个三元操作 - 我认为这几乎是不可读的答案 1 :(得分:1)
这对我有用:
#!/usr/bin/perl
use strict;
use warnings;
use XML::LibXML;
my $parser = XML::LibXML->new();
my $doc = $parser->parse_file('XXX.xml');
my $j = 0;
my @imm;
$imm[$j++] = $_->data
for $doc->findnodes(
"//meters/meter"
."/name[../value[\@solve = 'imm']]"
."/text()");
print for @imm;
我对您的代码进行了以下更改:
/string()
部分。它是对我所得到的错误所指示的函数的无效使用。solve
的值为imm
,而不是immediate
。BTW,将XPath表达式的中间位置改为
'/name[../value[@solve = "immediate"]]'
避免使用反斜杠。