Perl LIBXML:使用带有属性的findnodes来访问xml文件中的节点

时间:2014-02-19 09:53:58

标签: perl xml-libxml

XML文件如下所示:

<?xml version="1.0"?>
<application name="pos">
<artifact id="123" type="war" cycle="Release7-Sprint1">
<jira/>
<jenkins/>
<deployment/>
<scm>
  <transaction id="1234" user="">
    <file name=""/>
    <file name=""/>
  </transaction>
</scm>
</artifact>
</application>

当我使用属性(名称)的硬编码值而不是使用变量时,我的代码看起来如下并且工作正常。我正在引用该行(我的$ query =
    '//应用[@名称= “POS”]'; )

my $manifestDoc = $manifestFileParser->parse_file($manifestFile);
my $changeLogDoc = $changeLogParser->parse_file($changeLogXml );
my $changeLogRoot = $changeLogDoc->getDocumentElement;

#my $applicationName = pos;
my $query  = '//application[@name="pos"]';
my $applicationNode = $manifestDoc->findnodes($query);

my $artifactNode = $manifestDoc->createElement('artifact');
$artifactNode->setAttribute("id",$artifactID);
$artifactNode->setAttribute("type",$artifactType);
$artifactNode->setAttribute("cycle",$releaseCycle);
$applicationNode->[0]->appendChild($artifactNode);

但是如果我修改$ query变量来使用变量($ applicationName)而不是属性的硬编码值,它会给我一个编译错误,如下所示:

无法在updateManifest.pl行的未定义值上调用方法“appendChild”

修改后的代码:

 my $applicationName = "pos" ;
 my $query  = '//application[@name="$applicationName"]';

不确定是什么问题。与报价有什么关系? 非常感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

表达式'//application[@name="$applicationName"]'表示带有这些内容的文字字符串 - 没有用单引号插入变量。如果您使用双引号,则会插入@name$applicationName

您有三种选择:

  1. 使用双引号,但转义@

    qq(//application[\@name="$applicationName"])
    

    qq运算符相当于双引号"…",但可以使用任意分隔符,这样就无需转义字符串中的"

  2. 连接字符串:

    '//application[@name="' . $applicationName . '"]'
    

    这往往难以阅读。我会避免这种解决方案。

  3. 使用sprintf模式从模板构建字符串:

    sprintf '//application[@name="%s"]', $applicationName
    

    如果您还不知道printf模式,可以在perldoc -f sprintf中找到它们。