如何使用perl搜索特定字符串的xml文件?

时间:2015-06-08 19:48:44

标签: xml perl

$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不在

2 个答案:

答案 0 :(得分:3)

前两个主要问题:

  1. 您正在尝试打开名称以.xml>结尾的文件。

    open FILE, "<$inputFile>";
    

    应该是

    open FILE, "<$inputFile";
    

    嗯,不是真的。它应该是

    open(my $FILE, '<', $inputFile)
       or die("Can't open \"$inputFile\": $!\n");
    

    这避免了使用全局变量,这避免了文件名被视为除文件名之外的任何内容,并且这将检查open是否成功(是一个常见的失败点)。

  2. 您永远不会从文件句柄中读取。

    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结构/属性/内容更令人满意。