스크립트를 사용하여 설치 프로세스를 자동화하려고 합니다. 프로세스의 일부는 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>