2

これは私のサンプルxmlファイルです

<manifest>
 <default>
    <remote>remote1</remote>
    <revision>rev1</revision>
 </default>
 <project>
    <name>common</name>
    <path>opensource/device</path>
    <revision>sa</revision>
    <x-ship>oss</x-ship>
 </project>
 <project>
   <name>external</name>
   <path>source/tp</path>
   <x-ship>none</x-ship>
 </project>
 <project>
   <name>ws</name>
   <path>opensource/ws</path>
   <remote>nj</remote>
   <revision>myno</revision>
   <x-ship>none</x-ship>
 </project>
</manifest>

<path>これでは、 「opensource」文字列が含まれている場合にのみ、リビジョンの値を更新する必要があります。

私はたくさん検索しましたが、これを達成するのに役立つものは何も見つかりませんでした。以下のように位置に基づいて値を変更できました。誰かがこれを更新するのを手伝ってくれますか? または、これを行うためのより優れた Perl ライブラリがあれば教えてください。

#!/usr/bin/perl

use strict;
use warnings;

use XML::Simple;

my $xml_file = 'dev.xml';

my $xml = XMLin(
    $xml_file,
    KeepRoot => 1,
    ForceArray => 1,
);

$xml->{manifest}->[0]->{project}->[2]->{revision} = 'kyo';

XMLout(
    $xml,
    KeepRoot => 1,
    NoAttr => 1,
    OutputFile => $xml_file,
);
4

2 に答える 2

0

学習課題として、 を使用して上記のソリューションを複製することにしましたXML::LibXML。また、モジュールのドキュメントを理解するのが難しいため、この perlmonks の投稿をリソースとして使用して開始しましたStepping up from XML::Simple to XML::LibXML

use strict;
use warnings;

use XML::LibXML;

my $data = do { local $/; <DATA> };

my $dom = XML::LibXML->load_xml(string => $data);

for my $project ($dom->findnodes('//project')) {
    if (my ($path) = $project->findnodes("./path")) {
        next if $path->textContent() !~ /\bopensource\b/;
        my ($revision) = $project->findnodes("./revision")
            or next;

        my $oldval = $revision->textContent();
        $revision->removeChildNodes();
        $revision->appendText('open source - ' . $oldval);

    } elsif ( my $pathatt = $project->getAttribute('path') ) {
        next if $pathatt !~ /\bopensource\b/;
        $project->setAttribute('revision', 'open source - ' . $project->getAttribute('revision'))
    }
}

print $dom->documentElement()->toString();

__DATA__
<manifest>
 <default>
    <remote>remote1</remote>
    <revision>rev1</revision>
 </default>
 <project>
    <name>common</name>
    <path>NOTopensource/device</path>
    <revision>sa</revision>
    <x-ship>oss</x-ship>
 </project>
 <project path="opensource" revision="apple" name="platform" x-ship="none"/>
 <project>
   <name>external</name>
   <path>source/tp</path>
   <x-ship>none</x-ship>
 </project>
 <project>
   <name>ws</name>
   <path>opensource/ws</path>
   <remote>nj</remote>
   <revision>myno</revision>
   <x-ship>none</x-ship>
 </project>
</manifest>

結果:

<manifest>
 <default>
    <remote>remote1</remote>
    <revision>rev1</revision>
 </default>
 <project>
    <name>common</name>
    <path>NOTopensource/device</path>
    <revision>sa</revision>
    <x-ship>oss</x-ship>
 </project>
 <project path="opensource" revision="open source - apple" name="platform" x-ship="none"/>
 <project>
   <name>external</name>
   <path>source/tp</path>
   <x-ship>none</x-ship>
 </project>
 <project>
   <name>ws</name>
   <path>opensource/ws</path>
   <remote>nj</remote>
   <revision>open source - myno</revision>
   <x-ship>none</x-ship>
 </project>
</manifest>
于 2014-03-22T08:10:29.673 に答える