修改XML設定檔的腳本

修改XML設定檔的腳本

我正在嘗試使用腳本自動化安裝過程。過程的一部分是尋找 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 格式的方式編寫腳本。下面是修改兩個設定元素的 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>

相關內容