The XML file looks like below:
<?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>
My piece of code looks below and works fine when I use the hard coded value of attribute(name), instead of using a variable. I am referencing the line ( my $query =
'//application[@name="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);
But if I modify the $query variable to use a variable ($applicationName) instead of a hard coded value of attribute, it gives me a compilation error saying below:
Can't call method "appendChild" on an undefined value at updateManifest.pl line
Modified code:
my $applicationName = "pos" ;
my $query = '//application[@name="$applicationName"]';
Not sure what is wrong. Anything to do with quotes? Any help is much appreciated.
The expression '//application[@name="$applicationName"]'
means the literal string with those contents – no variables are interpolated with single quotes. If you'd use double quotes, then both @name
and $applicationName
would be interpolated.
You have three options:
Use double quotes, but escape the @
:
qq(//application[\@name="$applicationName"])
The qq
operator is equivalent to double quotes "…"
but can have arbitrary delimiters, which avoids the need to escape the "
inside the string.
Concatenate the string:
'//application[@name="' . $applicationName . '"]'
This often has a tendency to be hard to read. I'd avoid this solution.
Use a sprintf
pattern to build the string from a template:
sprintf '//application[@name="%s"]', $applicationName
If you don't already know printf
patterns, you can find them documented in perldoc -f sprintf
.