Script para modificar el archivo de configuración XML

Script para modificar el archivo de configuración XML

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 falsea trueo 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 xpathlo que es, en términos XML, una forma de buscar/seleccionar el contenido que desea y modificarlo.

Algo así como XML::Twiguna 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_xpathutiliza 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.

xpathes 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>

información relacionada