2013-09-26 3 views
1

Я пытаюсь добавить строку между <value></value>,значение Append в XML-узел с помощью Perl

<?xml version="1.0" encoding="UTF-8"?> 
<rs:alarm-request throttlesize="100" xmlns:rs="http://url.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.url.com"> 
    <rs:attribute-filter> 
    <search-criteria xmlns="http://www.url"> 
    <filtered-models> 
     <equals> 
     <attribute id="0x1144f50"> 
     <value></value> 
     </attribute> 
     </equals> 
     </filtered-models> 
    </search-criteria> 
    </rs:attribute-filter> 
    <!-- Models of Interest --> 
    <rs:target-models> 
    </rs:target-models> 
</rs:alarm-request> 

Я использовал следующий код, но я постоянно получаю: Не удается найти метод объекта «appendTextNode "через пакет" XML :: LibXML :: NodeList "

my $parser  = XML::LibXML->new(); 

# Insert devices MH to GETdevices_xmlbody template 
my $doc = $parser->parse_file($current_working_dir.'\GETdevices_xmlbody.xml'); 
my $elem = $doc->findnodes('//rs:attribute-filter/search-criteria/filtered-models/equals/attribute/value'); 

# $elem->removeChildNodes(); 
$elem->appendTextNode('STRING'); 
+0

Если ваш XPath будет соответствовать, вы можете использовать что-то вроде '$ elem-> get_node (1) -> appendTextNode ('STRING');' –

ответ

4

Вы можете использовать XML::Twig тоже:

Содержание script.pl:

#!/usr/bin/env perl 

use warnings; 
use strict; 
use XML::Twig; 

my $twig = XML::Twig->new(
    twig_handlers => { 
     '//rs:attribute-filter/search-criteria/filtered-models/equals/attribute/value' => sub { 
      $_->set_text('STRING'); 
     }, 
    }, 
    pretty_print => 'indented', 
)->parsefile(shift)->print; 

Выполнить это нравится:

perl script.pl xmlfile 

Это дает:

<?xml version="1.0" encoding="UTF-8"?> 
<rs:alarm-request throttlesize="100" xmlns:rs="http://url.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.url.com"> 
    <rs:attribute-filter> 
    <search-criteria xmlns="http://www.url"> 
     <filtered-models> 
     <equals> 
      <attribute id="0x1144f50"> 
      <value>STRING</value> 
      </attribute> 
     </equals> 
     </filtered-models> 
    </search-criteria> 
    </rs:attribute-filter> 
    <!-- Models of Interest --> 
    <rs:target-models></rs:target-models> 
</rs:alarm-request> 
3

Вы просили получить все узлы, соответствующие вашим критериям. Вам нужно зациклиться на них.

my $elems = $doc->findnodes('...'); 
for my $elem ($elems->get_nodelist) { 
    ... 
} 

Simpler:

my @elems = $doc->findnodes('...'); 
for my $elem (@elems) { 
    ... 
} 

Если вы просто ожидаете ровно один, вы могли бы просто захватить первый.

my ($elem) = $doc->findnodes('...'); 
+0

Это только одна часть проблемы. Другая заключается в том, что XPath не соответствует вообще, потому что начиная с '' есть другое пространство имен, с которым нужно иметь дело. Таким образом, необходимо использовать либо XML: LibXML :: XPathContext', либо выражение XPath должно быть переписано для выполнения только '/ * [local-name() =" element "]' match. –

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