2009-08-25 8 views
5

Tengo un archivo XML del formato:En Perl, ¿cómo puedo cambiar un elemento en un archivo XML sin cambiar el formato del archivo XML?

<outer1> 
    <inner1> 
     <name>Stonecold</name> 
     <profession>warrior</profession> 
     <org>wwf</org> 
    </inner1> 
    <inner1> 
     <name>Shanebond</name> 
     <profession>Bowler</profession> 
     <org>newzealand</org> 
    </inner1> 
    <inner1> 
     <name>brain schemidit</name> 
     <profession>Chairman</profession> 
     <org>Google</org> 
    </inner1> 
</outer1> 

que quieren cambiar el valor de Shanebond a Shane Bond.

Yo estaba usando XML::Simple, pero el resultado fue un hash.

Quiero el mismo formato que el archivo de entrada. E.g: el archivo de salida debe ser el siguiente:

<outer1> 
    <inner1> 
     <name>Stonecold</name> 
     <profession>warrior</profession> 
     <org>wwf</org> 
    </inner1> 
    <inner1> 
     <name>Shane Bond</name> 
     <profession>Bowler</profession> 
     <org>newzealand</org> 
    </inner1> 
    <inner1> 
     <name>brain schemidit</name> 
     <profession>Chairman</profession> 
     <org>Google</org> 
    </inner1> 
</outer1> 

Por favor, indique cómo hacerlo.

Gracias de antemano.

Quiero que el archivo de salida se guarde en el mismo directorio y si es posible con el mismo nombre. ¿Es posible?

+1

¿Qué pasa con un hash? – innaM

+0

el archivo xml es un archivo de configuración y el componente que lo está utilizando no puede leer el archivo hash. también si su formato se cambia después de crear el archivo, entonces también el componente no puede leer el valor del archivo de configuración –

+1

XMLin -> procesar contenidos -> XMLout – innaM

Respuesta

4

XML::Simple tiene opciones que le permiten especificar cómo de entrada se transforma en una estructura de datos Perl y la forma en que la estructura será de salida:

#!/usr/bin/perl 

use strict; 
use warnings; 

use XML::Simple; 

my $xml_file = 'b.xml'; 

my $xml = XMLin(
    $xml_file, 
    KeepRoot => 1, 
    ForceArray => 1, 
); 

$xml->{outer1}->[0]->{inner1}->[1]->{name} = 'Shane Bond'; 

XMLout(
    $xml, 
    KeepRoot => 1, 
    NoAttr => 1, 
    OutputFile => $xml_file, 
); 

XML::Simple se pone un poco difícil si haces algo interesante, porque su propósito no es ser una biblioteca de propósito general XML sino para proporcionar una forma simple de tratar con archivos de configuración escritos en XML.

CPAN tiene una plétora de XML related modules. A menos que se tratara de un problema aislado, sería útil investigar algunos de los módulos más adecuados y más adecuados.

+0

Quiero que el archivo de salida se guarde en el mismo directorio y, si es posible, con el mismo nombre. ¿Es posible? –

+0

@pchakraborty Por supuesto que es posible. Nifle incluso mostró cómo hacerlo. Los documentos explican 'OutputFile' claramente. Léalos ocasionalmente: Ellos ayudan. –

+0

intenté esto y está funcionando correctamente. Tengo que insertarlo en el código principal y luego verificar el resultado. gracias por tu ayuda. –

3

Ha intentado XMLout with OutputFile

De la documentación para XML :: Simple:

El comportamiento predeterminado de XMLout() es devolver el XML como una cadena. Si desea escribir el XML en un archivo, simplemente proporcione el nombre de archivo con la opción 'OutputFile'.
Esta opción también acepta un controlador de objetos IO - especialmente útil en Perl 5.8.0 y más tarde para la salida utilizando una codificación distinta de UTF-8, por ejemplo:

open my $fh, '>:encoding(iso-8859-1)', $path or die "open($path): $!"; 
XMLout($ref, OutputFile => $fh); 
+0

intenté esto y está funcionando correctamente. Tengo que insertarlo en el código principal y luego verificar el resultado. gracias por tu ayuda. –

8

Cuando se trata de leer o manipular un archivo XML, a menudo es XML::Twig la primera herramienta que uso.

Al principio pensé que tal vez una exageración para sus necesidades, pero luego me di cuenta de lo que vienen con una opción de parsefile_inplace():

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

XML::Twig->new(
    pretty_print => 'indented', 
    twig_handlers => { 
     name => sub { 
      $_->set_text('Shane Bond')->flush if $_->text eq 'Shanebond' 
     }, 
    }, 
)->parsefile_inplace('data.xml', 'bak_*'); 

NB. Si no desea conservar un archivo de copia de seguridad, elimine el segundo arg ('bak_ *').

4

¿Por qué molestarse en procesarlo como XML en absoluto? ¿Por qué no simplemente hacer un regexp-replace?

perl -pi -e 's/Shanebond/Shane Bond/' filename.xml 

Eso hará el reemplazo en su lugar, manteniendo el mismo nombre de archivo y todo.

Cuestiones relacionadas