2014-02-19 2 views
1

файл XML выглядит следующим образом:Perl Libxml: Использование findnodes с атрибутами для достижения узла в 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> 

Моего кусок кода выглядит ниже и хорошо работает, когда я использую жесткий кодированное значение атрибута (name) вместо использования переменной. Я ссылки на строку (мой $ запрос =
'// приложение [@ имя = "позиция"];)

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); 

Но если изменить переменную $ запроса использовать переменную ($ ApplicationName) вместо жестко закодированного значения атрибута, он дает мне ошибку компиляции говоря ниже:

Невозможно вызвать метод «AppendChild» на неопределенное значение в updateManifest.pl линии

Модифицированный код:

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

Не уверен, что не так. Что-нибудь делать с цитатами? Любая помощь очень ценится.

ответ

1

Выражение '//application[@name="$applicationName"]' означает буквенную строку с этим содержимым - никакие переменные не интерполируются с одинарными кавычками. Если бы вы использовали двойные кавычки, то были бы интерполированы и @name, и $applicationName.

У вас есть три варианта:

  1. Используйте двойные кавычки, но спасаясь от @:

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

    Оператор qq эквивалентно двойные кавычки "…" но могут иметь произвольные разделители, что позволяет избежать необходимо избегать " внутри строки.

  2. Concatenate строка:

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

    Это часто имеет тенденцию быть трудно читать. Я бы избегал этого решения.

  3. Используйте sprintf шаблон для создания строки из шаблона:

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

    Если вы уже не знаете printf шаблоны, вы можете найти их документально в perldoc -f sprintf.

+0

Большое спасибо. Я использовал вариант 1, и он сработал. – user1470220

+1

XPath также поддерживает одинарные кавычки. Поэтому я обычно иду с '// // application [\ @ name = '$ applicationName']". – nwellnhof

Смежные вопросы