$characterString = $verb[2];
$inputFile = $targetdirectory."/ppt/slides/slide".$slidenumber.".xml";
open FILE, "<$inputFile>";
for (@lines) {
if ($_ =~ /$characterString/) {
print "Matched $characterString \n ";
} else {
print "Did not match $characterString\n";
}
}
close FILE;
以下是XML文件中的示例:
<a:t>Bailey</a:t></a:r></a:p><a:p><a:pPr lvl="1"><a:lnSpc><a:spcPct val="90000"/>
这是输出:
PUB ENGINE: Version 5-26-2015
Did not match billybob
Did not match Bailey
Bailey在xml文件中,但billybob不在
答案 0 :(得分:3)
前两个主要问题:
您正在尝试打开名称以.xml>
结尾的文件。
open FILE, "<$inputFile>";
应该是
open FILE, "<$inputFile";
嗯,不是真的。它应该是
open(my $FILE, '<', $inputFile)
or die("Can't open \"$inputFile\": $!\n");
这避免了使用全局变量,这避免了文件名被视为除文件名之外的任何内容,并且这将检查open
是否成功(是一个常见的失败点)。
您永远不会从文件句柄中读取。
for (@lines) {
应该是
while (<FILE>) {
或者如果您采纳了我建议的更改,
while (<$FILE>) {
答案 1 :(得分:2)
我建议你采取错误的做法。 XML不能很好地解析基于行和正则表达式的解析 - 有多种方法可以创建语义相同的XML,它们与相同的正则表达式不匹配。
我必须稍微调整一下你的XML,因为它无效。我假设这是因为你提到你的XML 有效的'sample'。供参考 - 提供有效的样本XML非常有用 - 这意味着所有标签都可以打开/关闭。
所以我正在使用它:
<root>
<a:r>
<a:p>
<a:t>Bailey</a:t>
</a:p>
</a:r>
<a:p>
<a:pPr lvl="1">
<a:lnSpc>
<a:spcPct val="90000" />
</a:lnSpc>
</a:pPr>
</a:p>
</root>
请注意,这可以通过多种方式编写:
<root
><a:r
><a:p
><a:t
>Bailey</a:t></a:p></a:r><a:p
><a:pPr
lvl="1"
><a:lnSpc
><a:spcPct
val="90000"
/></a:lnSpc></a:pPr></a:p></root>
或者:
<root><a:r><a:p><a:t>Bailey</a:t></a:p></a:r><a:p><a:pPr lvl="1"><a:lnSpc><a:spcPct val="90000"/></a:lnSpc></a:pPr></a:p></root>
所有这些都意味着相同 - 并且希望说明为什么使用基于行的解析是一个坏主意。这可能不完全适用于您的用例,但我坚信在涉及XML时使用XML解析器并不是坏事。
无论如何 - 寻找元素。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
my $search = 'Bailey';
my $found;
XML::Twig->new(
twig_handlers => {
'_all_' => sub { $found++ if $_->text =~ m/$search/ }
}
)->parsefile($inputFile);
if ($found) {
print "Found $search\n";
}
else {
print "Didn't find $search\n";
}
注意 - 仅“查找”XML文本中的关键字,而不是“查找”任何属性中的关键字。这通常比盲目匹配XML结构/属性/内容更令人满意。