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>

관련 정보