Perlを使用してxmlファイルの行を変更してタグを削除しますか?

Perlを使用してxmlファイルの行を変更してタグを削除しますか?

行を変更してタグ全体を削除する必要があるXMLファイルがあるため、(client_23.xml)Perlスクリプトを思いつきました。

私のXMLファイルにはこのようなブロックがあります。<hello>collect_model = 1</hello>私のXMLファイルには1つのインスタンスしかありません。

<world>
    <hello>collect_model = 1</hello>
    <hello>enable_data = 0</hello>
    <hello>session_ms = 2*60*1000</hello>
    <hello>max_collect = string_integer($extract("max_collect"))</hello>
    <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello>
    <hello>output('{')</hello>
</world>

その行を次のように変更する必要があります。<hello>collect_model = 0</hello>したがって、ブロック全体を変更した後、次のようにする必要があります。

<world>
    <hello>collect_model = 0</hello>
    <hello>enable_data = 0</hello>
    <hello>session_ms = 2*60*1000</hello>
    <hello>max_collect = string_integer($extract("max_collect"))</hello>
    <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello>
    <hello>output('{')</hello>
</world>

2つ目は、同じXMLファイルからタグ全体を削除する必要があることです。

<derta-config>
    <data-users>2000</data-users>
    <test-users>2000</test-users>
    <attributes>hello world</attributes>
    <client-types>Client1</model-types>
    <target>price.world</target>
</derta-config>

そのため、Perlを使用する次のシェルスクリプトがあり、ファイルの一部の内容を置き換えている間に上記の2つの操作を実行しようとしますが(私は別の目的でこれを行います)、上記の2つの操作のために特別に追加したセクションでは、そうではありませんでした。仕事をして多くのエラーを印刷し始めました。

perl -0pe "s#<eval>collect_model = 0</eval>#<eval>collect_model = 1</eval> s#<derta-config>.* </derta-config>##sm;   s#<function>\s*<name>DUMMY_FUNCTION.+?</function>#$file#sm" client_"$client_id".xml > "$word"_new_file.xml

だから私はシェルスクリプトでこれを行うことができるかどうか疑問に思いました。つまり、シェルスクリプトを使用して上記の2つを削除し、その出力を3番目のステップで動作するPerlスクリプトに渡します。では、シェルスクリプトの出力を以下のPerlスクリプトに渡すことはできますか?これにより、上記の2つが削除されます。大丈夫ですか?

perl -0pe "s#<function>\s*<name>DUMMY_FUNCTION.+?</function>#$file#sm" client_"$client_id".xml > "$word"_dyn_model.xml

ここも同様$client_idです23$wordabc

私はこれがうまくいくことを望み、最も簡単なことは何でも私にうまくいくでしょう。上記の2つのことの例を見てみましょう。

ベストアンサー1

XML の解析に正規表現を使用しないでください。これは悪い考えです。これが悪い考えである主な理由は、多くの種類のXMLがあり、意味的に同じいくつかのXMLがかなり異なるパターンマッチングを持つ可能性があることです。

改行、スペース、単項タグなどを検討してください。

<element />
<element></element>

どちらも同じです。その後、インデント、改行、タグ分割などを実行できます。

<element 
    att1="fish"
    att2="carrot">

また有効です。

だから私もそう強く「パーサーの使用」をお勧めします。 Perlにはさまざまなオプションがあります。私の好きなものは次のとおりですXML::Twig

#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig->new( 'pretty_print' => 'indented_a' )->parse( \*DATA );

foreach my $hello ( $twig->findnodes('//hello') ) {
    if ( $hello->trimmed_text =~ m/collect_model/ ) {
        $hello->set_text('collect_model = 0');
    }
}

$_->delete for $twig->findnodes('//derta-config');

$twig->print;

__DATA__
<root>
<world>
    <hello>collect_model = 1</hello>
    <hello>enable_data = 0</hello>
    <hello>session_ms = 2*60*1000</hello>
    <hello>max_collect = string_integer($extract("max_collect"))</hello>
    <hello>max_collect = parenting(max_collect, max_collect, 1.0e99)</hello>
    <hello>output('{')</hello>
</world>
<derta-config>
    <data-users>2000</data-users>
    <test-users>2000</test-users>
    <attributes>hello world</attributes>
    <client-types>Client1</client-types>
    <target>price.world</target>
</derta-config>
</root>

なぜなら、あなたはPerlで次の行が好きだと思うからです:

perl -MXML::Twig -0777 -e 'my $twig = XML::Twig->parse (<>); $_->set_text("collect_model = 0") for grep { $_->text =~ m/collect_model/ } $twig->findnodes("//hello"); $_->delete for $twig->findnodes("//derta-config"); $twig -> print;'

おすすめ記事