Script para modificar o arquivo de configuração XML

Script para modificar o arquivo de configuração XML

Estou tentando automatizar um processo de instalação com um script. Parte do processo é encontrar certas seções do arquivo de configuração XML (visto abaixo) e alterar certos parâmetros de falsepara trueou vice-versa.

Existem muitas seções no arquivo de configuração que possuem a <enabled>tag (neste caso, é a <ssh>seção). Então, minha pergunta é: como posso procurar a <enabled>tag específica e modificá-la?

<ssh>
  <enabled>true</enabled>
  <ip>0.0.0.0</ip>
  <port>2024</port>
</ssh>

Responder1

Você realmente não deu um exemplo de XML grande o suficiente, então estou supondo um pouco.

Eu sugeriria que a ferramenta para o trabalho fosse um analisador XML decente e Perl.

Eu sugiro fortemente que você NÃO use:

Porque ambos são frágeis - eles funcionam, em circunstâncias controladas, mas você tem um código hacky e desagradável que pode quebrar misteriosamente um dia.

Em vez disso - use um analisador que suporte xpatho que é - em termos XML - uma maneira de localizar/selecionar o conteúdo desejado e modificá-lo.

Algo como XML::Twiguma baixa barreira de entrada. (XML::LibXML também é uma alternativa sólida, mas bastante mais exaustiva).

#!/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_xpathusa um tipo de formato de 'estrutura de diretório'. Ele suporta caminhos absolutos dentro do XML, bem como caminhos relativos. Da forma como é executado acima, ele operará no primeiro elemento que corresponder a esse caminho (XML permite vários).

Você pode, no entanto, fazer isso em um loop 'foreach':

foreach my $thing ( $twig -> get_xpath ('//enabled') ) {
   $thing -> set_text('false'); 
}

para desativar tudo.

xpathé bastante flexível - é uma forma de especificar caminho, elemento e atributos e éidealmente adequadopara navegar em XML de maneira semelhante a regex.

Então você tem construções como //for find recursivamente.

Ou //node[@name='test']para encontrar:

<node name="test">content</node>

Há umreferência rápida e útilisso fornece uma maneira fácil de ver como navegar em XML usando XPath.

Responder2

Como vários nós em seu arquivo de configuração possuem nós filhos com o mesmo nome, eu recomendaria escrever seu script de uma forma que realmente entenda o formato XML. Aqui está um exemplo Perl de modificação de dois de seus elementos de configuração:

#!/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,);

Aqui está minha 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>

E aqui está a saída:

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

informação relacionada