2012-04-18 85 views
1

感觉愚蠢的问这个问题,但到目前为止,它已经浪费了整个下午,并且仍然没有更接近解决方案。我正在自动化一些Jenkins实例的推出,并且我想复制现有的作业。XML在Perl中的解析和替换

我解析perl脚本中的config.xml文件,需要替换某些字符串元素。

我几乎到了那里与XML ::简单,但我发现它失去了我需要输出的数据结构。进一步阅读我发现这是XML :: Simple的工作原理。所以,我已经开始尝试XML ::的libxml

样本输入将是:

<project> 
    <properties> 
    <hudson.model.ParametersDefinitionProperty> 
     <parameterDefinitions> 
     <hudson.model.ChoiceParameterDefinition> 
      <name>environment</name> 
      <choices class="java.util.Arrays$ArrayList"> 
      <a class="string-array"> 
       <string>1</string> 
       <string>2</string> 
       <string>3</string> 
       <string>4</string> 
       <string>5</string> 
      </a> 
      </choices> 
     </hudson.model.ChoiceParameterDefinition> 
     </parameterDefinitions> 
    </hudson.model.ParametersDefinitionProperty> 
    <de.pellepelster.jenkins.walldisplay.WallDisplayJobProperty/> 
    </properties> 
</project> 

我所试图实现的,例如,是删除所有<string>n</string>元素,然后加入一些不同的。

和代码应该是比较简单:

my $p   = XML::LibXML->new; 
my $d   = $p->parse_string($input); 
my $params = $d->findnodes('/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition/choices'); 

这将返回一个节点列表。但我似乎无法操纵位于此列表中的元素。如果我这样做

print $params->to_literal; 

然后我可以看到我有我想操纵的数据。但我正在努力进行下一步。任何人都可以帮助我指出正确的方向吗?

+2

你应该看看[XML :: Twig](http://search.cpan.org/~mirod/XML-Twig-3.39/Twig.pm)。它提供了基于DOM的XML操作所需的一切。 – Demnogonis 2012-04-18 16:34:51

回答

1

nodeList你有一个列表XML::LibXML::Node对象。你想要做的是遍历每个节点调用父节点的removeChild函数传递子节点。

使用XML下面是一个例子::的libxml:

my $params = $d->findnodes('/project/properties/hudson.model.ParametersDefinitionProperty/parameterDefinitions/hudson.model.ChoiceParameterDefinition/choices/a'); 
foreach my $node ($params->[0]->childNodes()) { 

    $params->[0]->removeChild($node); 
} 

我假定元素的父节点将始终被命名为“A”,并且将只有在“选择”的一个节点节点。然后您可以使用print $d->toString();再次打印XML。

2

这是一个XML::Twig程序,它将删除a下的string标记。

use v5.10; 

my $xml = <<'HERE'; 
<project> 
    <properties> 
    <hudson.model.ParametersDefinitionProperty> 
     <parameterDefinitions> 
     <hudson.model.ChoiceParameterDefinition> 
      <name>environment</name> 
      <choices class="java.util.Arrays$ArrayList"> 
      <a class="string-array"> 
       <string>1</string> 
       <string>2</string> 
       <string>3</string> 
       <string>4</string> 
       <string>5</string> 
      </a> 
      </choices> 
     </hudson.model.ChoiceParameterDefinition> 
     </parameterDefinitions> 
    </hudson.model.ParametersDefinitionProperty> 
    <de.pellepelster.jenkins.walldisplay.WallDisplayJobProperty/> 
    </properties> 
</project> 
HERE 

use XML::Twig; 

my $twig = XML::Twig->new( 
    twig_handlers => { 
     a => sub { 
      foreach my $child ($_->children) { 
       say "Found ", $child->text; 
       $child->cut; 
       } 
      }, 
     }, 
    pretty_print => 'indented', 
    ); 

$twig->parse($xml); 
$twig->flush; 

如果要更改标记名称和文本,设置是相同的,但您稍微更改处理程序。

my $twig = XML::Twig->new( 
    twig_handlers => { 
     a => sub { 
      foreach my $child ($_->children) { 
       $child->set_tag('new_name'); 
       $child->set_text($child->text ** 2); 
       } 
      }, 
     }, 
    pretty_print => 'indented', 
    ); 

一旦您决定如何走DOM,Twig将处理细节以改变它。

+0

谢谢。我将在未来给XML :: Twig一个去。 – gnuchu 2012-04-19 08:08:38