Estoy intentando automatizar un proceso de instalación con un script. Parte del proceso consiste en encontrar ciertas secciones del archivo de configuración XML (que se ve a continuación) y cambiar ciertos parámetros de false
a true
o viceversa.
Hay muchas secciones dentro del archivo de configuración que tienen la <enabled>
etiqueta (en este caso es la <ssh>
sección). Entonces mi pregunta es, ¿cómo puedo buscar la <enabled>
etiqueta específica y modificarla?
<ssh>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>2024</port>
</ssh>
Respuesta1
Realmente no has dado un ejemplo XML lo suficientemente grande, así que estoy adivinando un poco.
Sugeriría que la herramienta para el trabajo sea un analizador XML decente y Perl.
Le sugiero encarecidamente que NO utilice:
Porque ambos son frágiles: en cierto modo funcionan, en circunstancias controladas, pero tienes un código desagradable que puede romperse misteriosamente algún día.
En su lugar, utilice un analizador que admita xpath
lo que es, en términos XML, una forma de buscar/seleccionar el contenido que desea y modificarlo.
Algo así como XML::Twig
una barrera de entrada baja. (XML::LibXML también es una alternativa sólida, pero bastante más exhaustiva).
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
#parse the content - you probably want `parsefile` here instead.
my $twig = XML::Twig -> new ( pretty_print => 'indented_a' ) -> parse ( \*DATA );
#select the node you want, alter it.
$twig -> get_xpath('./ssh/enabled',0) -> set_text('false');
#print the output (to STDOUT) - you can print {$output_fh} $twig->sprint; instead
$twig -> print;
__DATA__
<xml>
<www>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>80</port>
</www>
<ssh>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>2024</port>
</ssh>
<smtp>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>25</port>
</smtp>
</xml>
Nota: get_xpath
utiliza un tipo de formato de 'estructura de directorios'. Admite rutas absolutas dentro del XML, así como rutas relativas. La forma en que se ejecuta arriba, operará en el primer elemento que coincida con esa ruta (XML permite múltiples).
Sin embargo, puedes hacerlo en un bucle 'foreach':
foreach my $thing ( $twig -> get_xpath ('//enabled') ) {
$thing -> set_text('false');
}
para desactivar todo.
xpath
es bastante flexible: es una forma de especificar la ruta, el elemento y los atributos y esidealmente adaptadopara navegar XML de forma similar a una expresión regular.
Entonces tienes construcciones como //
for find recursivamente.
O //node[@name='test']
para encontrar:
<node name="test">content</node>
Hay unareferencia rápida y prácticaeso brinda una manera fácil de ver cómo navegar XML usando xpath.
Respuesta2
Dado que varios nodos en su archivo de configuración tienen nodos secundarios con el mismo nombre, recomendaría escribir su script de una manera que realmente comprenda el formato XML. Aquí hay un ejemplo de Perl sobre cómo modificar dos de sus elementos de configuración:
#!/usr/bin/perl
use strict;
use warnings;
use XML::Simple;
my $config = 'config.xml';
my $xml = XMLin($config, KeepRoot => 1, ForceArray => 1,);
$xml->{config}->[0]->{ssh}->[0]->{enabled} = 'false';
$xml->{config}->[0]->{web}->[0]->{ip} = '127.0.0.1';
XMLout($xml, KeepRoot => 1, NoAttr => 1, OutputFile => $config,);
Aquí está mi entrada config.xml
:
<config>
<ssh>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>2024</port>
</ssh>
<web>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>80</port>
</web>
</config>
Y aquí está el resultado:
<config>
<ssh>
<enabled>false</enabled>
<ip>0.0.0.0</ip>
<port>2024</port>
</ssh>
<web>
<enabled>true</enabled>
<ip>127.0.0.1</ip>
<port>80</port>
</web>
</config>