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

相关内容