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 false
para true
ou 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 xpath
o que é - em termos XML - uma maneira de localizar/selecionar o conteúdo desejado e modificá-lo.
Algo como XML::Twig
uma 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_xpath
usa 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>