使用Perl解析XML文件

3

我正在尝试从以下结构的XML文件中提取两个特定属性的值:

<environment>
    <applications>
       <application1>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applicaitons> 
</environment>

我希望能读取属性“host”和“port”的值。

我已经尝试过下面的代码,但对我来说不起作用。

#!/usr/local/bin/perl -w

use XML::XPath;

my $file = "configuration.xml";
my $xp = XML::XPath->new(filename => $file);

my $hname = $xp->find('/environment/applications/application1/app-config/server/@host');
my $pnumber = $xp->find('/environment/applications/application1/app-config/server/@port');


print $hname;

当我运行这个命令时,它没有返回任何输出。提前致谢。

6
我想说你是一股清新的空气。非常感谢你使用XML解析器来分析XML,而不是使用正则表达式! - CanSpice
4个回答

4

你的XML无效!修复它就可以正常工作。

$ perl test.pl
boxA

1
请将您的应用程序标签进行修正,并关闭application1标签。 - Dave G

4

无论何时,都要以以下方式开始编写您的Perl脚本;

use strict;

在调试时,还要执行以下操作;

use warnings;

这意味着你的XML格式有误。

修复你的XML,它就能正常工作!


实际上,即使没有设置警告/严格模式,它也总是显示错误。 - a'r
我在shebang行中错过了-w开关,这是公平的。不过我仍然坚持使用严格模式的注释;-) - Roger

2

</applicaitons> 应该拼写为 </applications>。在你的 XML 文档中进行替换。源代码没问题。


哈哈哈。看来我的xpath是错了,而不是XML本身的问题。发现下划线和破折号之间的差异。谢谢大家的帮助! ;) - sandster007
1
在你提出的问题中,你的XML是错误的,修正后,你现有的XPath就没问题了。无论如何,很高兴你解决了问题。 - Roger

0
使用XML::Simple。它很简单。
尝试以下代码:
use strict;
use warnings;
use XML::Simple;
my $xml = XMLin( <<XML );
<environment>
    <applications>
       <application1>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applicaitons> 
</environment>
XML
print $xml->{"applications"}{"app-config"}{"server"}{"host"} . "\n";
print $xml->{"applications"}{"app-config"}{"server"}{"port"} . "\n";

在您的XML片段上,您将会收到以下错误:

mismatched tag at line 7, column 9, byte 159 at C:/Perl64/lib/XML/Parser.pm line 187

由于提示存在不匹配的标签,我开始检查XML文件,直到找出格式错误并解决它们,因此我一直在处理XML错误,直到最终得到:

use strict;
use warnings;
use XML::Simple;
my $xml = XMLin( <<XML );
<environment>
    <applications>
          <app-config>
             <server host="boxA" port="1234"/>
           </app-config>
       </applications> 
</environment>
XML
print $xml->{"applications"}{"app-config"}{"server"}{"host"} . "\n";
print $xml->{"applications"}{"app-config"}{"server"}{"port"} . "\n";

现在程序产生了预期的结果:

boxA
1234

正如你所看到的,它帮助我快速发现了错误的来源,并且没有额外的配置 XML::Simple 就可以实现一个非常自然的映射到 perl 哈希表中,这是我们都非常喜欢的 :-) ... 简单。


4
这是针对简单的XML(大多数XML并不简单)的。 - Quentin
好的,受到负评的启发,我来详细说明一下。我不反对@David的观点,但XML::Simple适用于许多XML,并且如果需要,您可以开始调整选项并处理更多的XML。如果您想要扩展或处理一些非常复杂的XML,那么可能是时候转移到其他模块了。但是,在这种情况下,看看它有多容易! - harschware
我怀疑这些踩的原因是因为更换XML模块并不能解决问题(问题在于XML格式不正确)。 - Quentin
好的,我明白你的观点,但如果 OP 一开始使用 XML::Simple,他就会得到适当的错误消息来帮助他解决自己的问题。使用这个模块会节省一些痛苦和在 stack overflow 上发帖的时间。我让我的答案保持不变,也许它会帮助其他人。 - harschware

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接