XML替换标记的值和添加标记

3

需要帮助更新XML文件。我查阅了这个链接,它对我很有帮助。

Perl代码:查找并替换XML文件中的标签值

接着,我创建了下面的代码,但仍需要更多帮助。我想要替换的标签值是“numCoreThreads”。

当我提供一个标签值时,它替换了那个值,并且运行得很好。

  • I would want the code to replace any value that is present to given value.
  • Also, How can I add a new tag under a parent tag. Exp Add Tag -

    <OptimizeThreshold>250</OptimizeThreshold> under
    <ftOptimizeThreshold>1000</ftOptimizeThreshold>
    

我的 XML -->

<svr_config>
<port>34343</port>
<PortMapper>false</PortMapper>
<numCoreThreads>12</numCoreThreads>

<plugins>
    <plugin>

        <userDefined>
            <ftOptimizeThreshold>1000</ftOptimizeThreshold>
        </userDefined>
    </plugin>
</plugins>

当前代码 -->

#!C:\strawberry\perl

use strict;
use warnings;

use XML::Twig;

XML::Twig->new( twig_roots =>    { numCoreThreads => sub { $_->flush }, },
            twig_handlers => { 'numCoreThreads[string()="12"]' => sub { $_->set_text(       '5000'); } },
            twig_print_outside_roots => 1,
          )
      ->parsefile_inplace( 'config.xml');

尝试使代码更加动态,比如读取输入文件,然后根据从输入文件中读取的参数更新xml。我知道……运行循环会再次打印整个文件……我们能优化它吗?

我的输入文件如下:

numCoreThreads: 20
OptimizeThreshold: ftOptimizeThreshold: 250

我制作的代码看起来像这样:

#!C:\strawberry\perl

use strict;
use warnings;
use XML::Twig;
open(IN1,"INPUT_FTS_XML_PRIMARY.txt");

while(my $r=<IN1>)
{
    $r=~/(.*:)\s(.*)/;
    my $c1=$1;
    my $d1=$2;
    my $f1=$3
my $twig = XML::Twig->new(
twig_handlers => {
    '$c1' => sub { $_->set_text( 'd1' ) },
    if (defined $f1)
    {
    '$d1' => sub {
        my $e = XML::Twig::Elt->new( '$c1' => '$f1' );
        $e->move( after => $_ );
    },}  
},  
pretty_print => 'indented',
)->parsefile( shift )->print;
}
1个回答

3
我会在 twig_handlers 内部完成所有工作:
#!/usr/bin/env perl

use strict;
use warnings;
use XML::Twig;

my $twig = XML::Twig->new(
    twig_handlers => {
        'numCoreThreads' => sub { $_->set_text( '5000' ) },
        'ftOptimizeThreshold' => sub {
            my $e = XML::Twig::Elt->new( 'OptimizeThreshold' => '250' );
            $e->move( after => $_ );
        },  
    },  
    pretty_print => 'indented',
)->parsefile( shift )->print;

运行方式如下:

perl script.pl xmlfile

它产生:

<svr_config>
  <port>34343</port>
  <PortMapper>false</PortMapper>
  <numCoreThreads>5000</numCoreThreads>
  <plugins>
    <plugin>
      <userDefined>
        <ftOptimizeThreshold>1000</ftOptimizeThreshold>
        <OptimizeThreshold>250</OptimizeThreshold>
      </userDefined>
    </plugin>
  </plugins>
</svr_config>

更新:请查看评论。

用参数读取文件的每一行,以冒号分隔并将字段保存在适合您需求的数据结构中。然后仅需使用这些值的内容替换文字字面量即可。

die qq|Usage: perl $0 <arg-file> <xml-file>\n| unless @ARGV == 2;

open my $fh, '<', shift or die;
while ( <$fh> ) {
    chomp;
    my @f = split /\s*:\s*/;
    ## Save fields in a data structure.
}

谢谢伙计...但是关于我的第一个问题...对于numCoreThreads参数,无论字符串是什么,我该如何替换任何值..在这种情况下是12...但它能否仅搜索标签并替换目标值...再次感谢 :) - Arun Ganesh
1
@ArunGanesh:删除条件[string()="12"]。我加上它是因为它在你的原始代码中,但我已经编辑了答案以将其删除。 - Birei
谢谢,我会测试并回来询问更多问题...有关于XML Twig的好指南、示例等吗? - Arun Ganesh
1
@ArunGanesh:它的 pod 文档:perldoc XML::Twig - Birei
1
@ArunGanesh:这与 xml 问题无关。它取决于你使用的数据结构以及如何保存你的数据。如果你使用哈希表,numCoreThreads 作为键,20 作为值,则将字面量 5000 替换为 hash['numCoreThreads']。如果你使用数组并将值保存在第一个位置,则使用 array[0] 替换字面量。请查看 perldsc 文档页面。 - Birei
显示剩余9条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接