web-dev-qa-db-ja.com

XML設定ファイルを変更するスクリプト

スクリプトを使用してインストールプロセスを自動化しようとしています。プロセスの一部は、XML構成ファイル(以下を参照)の特定のセクションを検索し、特定のパラメーターをfalseからtrueにまたはその逆に変更することです。

設定ファイル内には、<enabled>タグ(この場合は<ssh>セクション)を持つ多くのセクションがあります。だから、私の質問は、特定の<enabled>タグを検索して変更するにはどうすればよいですか?

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

十分な大きさのサンプルXMLを実際に提供していないので、少し推測しています。

この仕事のツールはまともなXMLパーサーとPerlであることをお勧めします。

以下を使用しないことを強くお勧めします。

どちらももろいので、制御された状況では一種の作業ですが、ある日不思議なことに壊れてしまう可能性のある厄介なコードがあります。

代わりに、-XML用語で-必要なコンテンツを検索/選択して変更する方法であるxpathをサポートするパーサーを使用します。

XML::Twigのようなものは、参入障壁が低くなります。 (XML :: LibXMLも確実な代替手段ですが、より網羅的です)。

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

注-get_xpathは、「ディレクトリ構造」のような形式を使用します。 XML内の絶対パスと相対パスをサポートします。上記で実行する方法では、そのパスに一致する最初の要素で動作します(XMLでは複数を許可します)。

ただし、「foreach」ループで実行できます。

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

すべてを無効にします。

xpathは非常に柔軟性があります-パス、要素、属性を指定する方法であり、正規表現のようなXMLをナビゲートするのに理想的に適していますマナー。

したがって、再帰的に検索するための//などの構造があります。

または//node[@name='test']で検索:

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

便利なクイックリファレンス があり、xpathを使用してXMLをナビゲートする方法を簡単に確認できます。

2
Sobrique

構成ファイル内の複数のノードには同じ名前の子ノードがあるため、実際にXML形式を理解できる方法でスクリプトを作成することをお勧めします。 2つの構成要素を変更するPerlの例を次に示します。

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

これが私の入力です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>

そして、これが出力です:

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