2013-09-10 2 views
2

У меня есть XML-файл (information.xml). Мне нужно извлечь значения элементов и атрибутов из этого XML-файла и вставить эти значения элементов и атрибутов в другой файл XML (build.xml). Я должен изменить файл build.xml, заполнив соответствующие значения и теги элементов из файла information.xml.Как реально изменить значения XML-файла с помощью XML :: LibXML

Для этого я должен использовать XML :: LibXML. Я могу извлечь значения элементов и атрибутов от information.xml. Но, я не могу открыть и заполнить эти значения в build.xml

Пример:

information.xml

<info> 
    <app version="10.5.10" long_name ="My Application"> 
    <name> MyApp </name> 
    <owner>larry </owner> 
    <description> This is my first application</description> 
    </app> 
</info> 

build.xml

<build long_name="" version=""> 
    <section type="Appdesciption"> 
    <description> </description> 
    </section> 
    <section type="Appdetails"> 
    <app_name> </app_name> 
    <owner></owner> 
    </section> 
</build> 

Теперь моя задача состоит в том, чтобы извлечь значение владельца от information.xml, откр. build.xml, поиск метки владельца в build.xml и поставьте извлеченное значение там.

Сценарий Perl выглядит следующим образом:

#!/usr/bin/perl 
use strict; 
use warnings; 
use XML::LibXML; 
my $file1="/root/shubhra/myapp/information.xml"; 
my $file2="/root/shubhra/myapp/build.xml"; 

my $parser = XML::LibXML->new(); 
my $doc = $parser->parse_file($file1); 
foreach my $line ($doc->findnodes('//info/app')) 
{ 
    my $owner= $line->findnodes('./owner'); # 1st way 
    print "\n",$owner->to_literal,"\n"; 

    my ($long_name) = $line->findvalue('./@long_name'); # 2nd way 
    print "\n $long_name \n"; 

    my $version = $line->findnodes('@version'); 
    print "\n",$version->to_literal,"\n"; 
} 

my $parser2 = XML::LibXML->new(); 
my $doc2 = $parser2->parse_file($file2); 
foreach my $line2 ($doc2->findnodes('//build')) 
{ 
    my ($owner2)= $line2->findnodes('./section/owner/text()'); 

    my ($version2)=$line2->findvalue('./@version'); 

    print "\n Build.xml already has version : $version2 \n"; 
    print "\n Build.xml already has owner :",$owner2->to_literal; 

    $owner2->setData("Windows Application 2"); # Not changing build.xml 
    $line2->setAttribute(q|version|,"60.60.60"); # Not changing build.xml 
    my $changedversion = $line2->getAttribute(q|version|); 
    #superficially changed but didn't changed build.xml content 
    print "\n The changed version is : $changedversion"; 
} 

build.xml выглядит следующим образом:

<build long_name="" version="9.10.10"> 
<section type="Appdesciption"> 
<description> </description> 
</section> 
<section type="Appdetails"> 
<app_name> </app_name> 
<owner>shubhra</owner> 
</section> 
</build> 

my $doc3 = XML::LibXML->load_xml(location => $file2, no_blanks => 1); 
my $xpath_expression = '/build/section/owner/text()'; 
my @nodes = $doc3->findnodes($xpath_expression); 
for my $node (@nodes) { 
    my $content = $node->toString; 
    $content = $owner; 
    $node->setData($content); 
} 
$doc->toFile($file2 . '.new', 1); 
+0

Что вы пробовали? Не можете ли вы подумать о каких-либо методах DOM, которые могут быть полезны?Возможно, вы хотите перечитать документацию на [узлах DOM] (https://metacpan.org/module/XML::LibXML::Node) и [XML-элементы] (https://metacpan.org/module/XML :: LibXML :: Element). – amon

+0

Я попытался сделать это, используя параметр findnode и findvalue. Используя findnode, я перехожу к конкретному узлу и используя findvalue, я извлекаю вывод в переменной. Но, когда я пытаюсь поместить это значение переменной в build.xml, я не могу изменить содержимое. –

+1

OP, вам нужно показать, что вы сделали, чтобы мы могли вам помочь. Я не вижу, что вы пытались использовать в Perl-коде за последние 3 дня. – Zaid

ответ

2

Следующая не может найти что-нибудь (установка $owner2 в undef), так как owner не имеет никакого текста:

my ($owner2) = $line2->findnodes('./section/owner/text()'); 

Вы хотите

my ($owner2) = $line2->findnodes('./section/owner'); 

Это влечет за собой изменение

print "\n Build.xml already has owner :", $owner2->to_literal; 

в

print "\n Build.xml already has owner :", $owner2->textContent; 

и

$owner2->setData("Windows Application 2"); 

в

$owner2->removeChildNodes(); 
$owner2->appendText("Windows Application 2"); 

Вы подразумеваете вы хотите следующее не меняет build.xml, но даже не упоминает build.xml:

$line2->setAttribute(q|version|, "60.60.60"); 

Это изменение $doc2, но вам необходимо будет добавить следующий код для изменения build.xml:

$doc2->toFile('build.xml'); 
+0

Огромное вам спасибо за то, что вы помогли мне и дали мне знать, что делать. Я новичок в модуле Libxml. Но, пожалуйста, объясните на примере: ---> почему вы используете функцию removeChildNodes(). Что если, если у меня есть «много узлов/элементов» с «одним и тем же именем», присутствуют под одним тегом. Пример. Если у меня есть общий диск с тремя дисками в главном теге. Теги выглядеть следующим образом:

+0

Не могли бы вы объяснить! –

+0

Re "почему вы используете функцию removeChildNodes().", Чтобы удалить любой существующий текстовый узел перед добавлением нового. – ikegami

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