我基本上是一名java开发人员,但我的客户在perl中给了我一个小任务。我的任务是获取xml输入,我需要搜索一个元素并打印它的值(在String变量中保存值)。例如在xml下面我想读取FileName标签的值。
<ConnectHome SchemaVersion="1.0.8">
<TransType>0090</TransType>
<Node>
<ExternalFiles>
<FileName>some file name</FileName>
</ExternalFiles>
</Node>
</ConnectHome>
我正在使用XML:简单的库来解析XML。我也可以使用下面的代码读取元素的值。
$xmlSimple = new XML::Simple(KeepRoot => 1);
$dataXML = $xmlSimple->XMLin("RepeatedElement.xml");
my $fileNameValue = $dataXML->{ConnectHome}->{Node}->{ExternalFiles}->{FileName};
但我的客户想要使用元素名称搜索值,因为路径可能会在xml中发生变化。
"FileName"
而不是硬编码路径。
所以我的问题是如何通过元素的名称而不是硬编码路径获取值?有没有按名称搜索元素的方法?我将在字符串变量中传递元素的名称。
答案 0 :(得分:3)
如果这是您唯一的任务,您可以切换到另一个库,例如XML::Twig
,这将使这更容易。
Also consider this note from XML::Simple
's documentation
不鼓励在新代码中使用此模块。其他模块可用,提供更直接和一致的接口。特别强烈建议使用XML :: LibXML。
此模块的主要问题是大量选项以及这些选项交互的任意方式 - 通常会产生意外结果。
欢迎使用包含错误修复和文档修补程序的修补程序,但不太可能添加新功能。
以下是使用XML::Twig
的示例。为你感兴趣的元素设置处理程序。(在这种情况下,我将文本内容推送到数组中)。
use XML::Twig;
my @filenames;
my $twig = XML::Twig->new(
twig_handlers => {FileName => sub {push @filenames, $_->text}}
);
$twig->parse(*DATA);
# $twig->parsefile('RepeatedElement.xml'); # you probably want this
say ">>$_<<"for @filenames;
__DATA__
<ConnectHome SchemaVersion="1.0.8">
<TransType>0090</TransType>
<Node>
<ExternalFiles>
<FileName>some file name</FileName>
</ExternalFiles>
</Node>
</ConnectHome>
另一种方法是使用一些基本的解析库,例如XML::Parser
,XML::Parser::Expat
,XML::TokeParser
,XML::LibXML
并自己组装文本,尽管这可能也是对于这么简单的任务来说很乏味。
您还可以使用XML::XPath
(xpath是一种用于在DOM树中导航的查询语言):
use XML::XPath;
my $xp = XML::XPath->new(filename => 'RepeatedElement.xml');
my $filename = $xp->find('//FileName');