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