スクリプトを使用してインストールプロセスを自動化しようとしています。プロセスの一部は、XML構成ファイルの特定の部分(以下に示す)を見つけて、特定のパラメーターを変更するか、その逆をfalse
変更することですtrue
。
構成ファイルの多くのセクションにこの<enabled>
タグがあります(この場合はこの<ssh>
セクション)。だから私の質問は、特定の<enabled>
タグをどのように検索して編集できるかということです。
<ssh>
<enabled>true</enabled>
<ip>0.0.0.0</ip>
<port>2024</port>
</ssh>
答え1
実際には十分に大きなXMLの例を提供していないので、推測してみました。
私がその仕事にお勧めするツールは良いXMLパーサーとPerlです。
以下を使用しないことをお勧めします。
どちらも脆弱であるため、制御された環境で動作しますが、いつか不思議に何かを破ることができる不快なハッカーコードがあります。
代わりに、サポートされているパーサーを使用してxpath
XML用語で必要なものを見つけて選択して変更する方法です。
例えば、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
構成ファイルの複数のノードには同じ名前の子ノードがあるため、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>