3

親愛なるPerlとXMLの達人

XPathを使用してXMLファイル内の値を更新するタスクがあります。 私はPerlのライブラリを使用して、XMLファイルを読み取り、変更し、保存します。
XML::LibXML

# Read XML file
my $parser = XML::LibXML->new();
my $doc = $parser->load_xml(location => $config_file);
my $root = $doc->documentElement();

# Alter nodes\attributes
foreach (keys %environment_values) {
    my @nodes = $root->findnodes($_);
    if (scalar @nodes < 1) {
        print "ERROR: element not found in $config_file by XPath: $_\n";
        die;
    } elsif (scalar @nodes > 1) {
        print "ERROR: more than 1 element (" . scalar @nodes . ") is found in $config_file by XPath: $_\n";
        die;
    }
    my $node = $nodes[0];
    if  ($node->nodeType == XML_ELEMENT_NODE) {
        $node->removeChildNodes();
        $node->appendText($environment_values{$_});
    } elsif ($node->nodeType == XML_ATTRIBUTE_NODE) {
        $node->setValue($environment_values{$_});
    } else {
        print "ERROR: unknown node type: " . $node->nodeType . "\n";
        die;
    }
}

# Save the resulting XML file
open (my $fh, '>:raw', $config_file) or die $!;
print $fh $doc->toString();
close $fh;

元のファイルと非常によく似たファイルを生成しますが、それでもいくつかの厄介な問題があります。

  1. 改行文字(行末)はUnixスタイルですが、元のファイルにはWindowsスタイルがあります。
  2. 終了/>の前のスペースが削除されます。たとえば、に<node />なり<node/>ます。

これらを修正するチャンスはありますか?元のファイルとまったく同じXMLファイルを取得したいと思っていますが、修正する属性値が異なるだけです...

<xmlpoke>PS私はNAntのシンプルさが本当に好きです。ただし、この作業にはPerlを使用する必要があります。

4

2 に答える 2

3

改行への答えはあなたが使用しているモードにあるかもしれないと思います。

http://perldoc.perl.org/PerlIO.html#Defaults-and-how-to-override-themによると:

プラットフォームがMS-DOSのようであり、通常、テキストファイルの「\ n」変換へのCRLFを実行する場合、デフォルトのレイヤーは次のとおりです。

   unix crlf

(低レベルの「unix」レ​​イヤーは、プラットフォーム固有の低レベルレイヤーに置き換えることができます。)

于 2012-08-31T16:00:46.887 に答える
2

一般に、要求しているように見えるものを正確に取得することはできません。たとえば、一重引用符と二重引用符の丸い属性値の区別や、タグ内のスペースが失われます。

Perlで一度読み取り、変更せずに書き出してから、スクリプトを実行して、これら2つのファイルを比較するのが最善の方法です。

于 2012-09-01T04:24:43.580 に答える