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입니다.

다음을 사용하지 않는 것이 좋습니다.

둘 다 취약하기 때문에 통제된 환경에서 작동하지만 언젠가는 신비롭게 무언가를 깨뜨릴 수 있는 불쾌한 해커 코드가 있습니다.

대신 지원되는 파서를 사용하여 xpathXML 용어로 필요한 것을 찾아 선택하고 수정하는 방법입니다.

예를 들어, 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>

관련 정보