【问题标题】:XML Replace Value for a Tag and Add a Tag标记的 XML 替换值并添加标记
【发布时间】:2025-12-05 13:30:01
【问题描述】:

在更新 XML 方面需要帮助。 我浏览了这个链接,它非常有帮助。

Perl code for Find and replace a tag value in XML

接下来,我创建了以下代码,但仍需要更多帮助。 我要替换的标记值是“numCoreThreads”。

当我给一个标签值时,它会替换该值并正常工作。

  • 我希望代码替换给定的任何值 价值。
  • 另外,如何在父标签下添加新标签。 Exp 添加标签 -

    <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;
}

【问题讨论】:

    标签: xml perl replace tags add


    【解决方案1】:

    我会在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>
    

    更新:见 cmets。

    使用参数读取文件的每一行,用冒号分隔并将字段保存在适合您需要的数据结构中。然后简单地将文字替换为这些值的内容。

    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...但是可以吗仅搜索标签并替换目标值....再次感谢 :)
    • @ArunGanesh:删除条件[string()="12"]。我放它是因为它在您的原始代码中,但我已经编辑了答案以将其删除。
    • 谢谢,如果我有更多问题,我会测试并回复......任何关于 XML Twig 的 gud 指南......示例等?
    • @ArunGanesh:它的pod 文档:perldoc XML::Twig
    • @ArunGanesh:这与xml 问题无关。这取决于您使用什么数据结构以及如何保存数据。如果您使用以numCoreThreads 作为键并以20 作为值的散列,请将文字5000 替换为hash['numCoreThreads']。如果您使用数组并将值保存在第一个位置,请将文字替换为array[0],依此类推。查看perldsc 文档页面。