Skript zum Ändern der XML-Konfigurationsdatei

Skript zum Ändern der XML-Konfigurationsdatei

Ich versuche, einen Installationsprozess mit einem Skript zu automatisieren. Ein Teil des Prozesses besteht darin, bestimmte Abschnitte der XML-Konfigurationsdatei (siehe unten) zu finden und bestimmte Parameter von falsein trueoder umgekehrt zu ändern.

Es gibt viele Abschnitte in der Konfigurationsdatei, die das <enabled>Tag haben (in diesem Fall ist es der <ssh>Abschnitt). Meine Frage ist also, wie kann ich nach dem bestimmten <enabled>Tag suchen und es ändern?

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

Antwort1

Sie haben nicht wirklich ein ausreichend großes Beispiel-XML angegeben, daher muss ich nur ein bisschen raten.

Als geeignetes Werkzeug für diese Aufgabe würde ich einen ordentlichen XML-Parser und Perl vorschlagen.

Ich rate Ihnen dringend davon ab, die folgenden Substanzen zu verwenden:

Weil beide anfällig sind. Unter kontrollierten Umständen funktionieren sie zwar irgendwie, aber Sie haben einen fehlerhaften Code, der eines Tages auf mysteriöse Weise kaputt gehen könnte.

Verwenden Sie stattdessen einen Parser, der dies unterstützt. xpathDies ist - in XML-Begriffen - eine Möglichkeit, den gewünschten Inhalt zu finden/auszuwählen und zu ändern.

Etwas wie XML::Twigstellt eine niedrige Einstiegshürde dar. (XML::LibXML ist auch eine solide Alternative, aber etwas umfassender).

#!/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>

Hinweis: get_xpathVerwendet wird eine Art „Verzeichnisstruktur“. Es werden absolute Pfade innerhalb des XML sowie relative Pfade unterstützt. So wie es oben ausgeführt wird, wird es auf das erste Element angewendet, das diesem Pfad entspricht (XML erlaubt mehrere).

Sie können dies jedoch in einer „foreach“-Schleife tun:

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

um alles zu deaktivieren.

xpathist ziemlich flexibel - es ist eine Möglichkeit, Pfad, Element und Attribute anzugeben und istideal geeignetzur Navigation in XML auf Regex-ähnliche Weise.

Sie verfügen also über Konstrukte wie „ //for find rekursiv“.

Oder //node[@name='test']finden Sie:

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

Da ist einpraktische KurzreferenzAuf diese Weise lässt sich auf einfache Weise die Navigation in XML mithilfe von XPath nachvollziehen.

Antwort2

Da mehrere Knoten in Ihrer Konfigurationsdatei untergeordnete Knoten mit demselben Namen haben, empfehle ich, Ihr Skript so zu schreiben, dass es das XML-Format tatsächlich versteht. Hier ist ein Perl-Beispiel zum Ändern zweier Ihrer Konfigurationselemente:

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

Hier ist mein Beitrag 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>

Und hier ist die Ausgabe:

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

verwandte Informationen