如何使用Perl LibXML :: XML生成一元XML标记

时间:2015-03-05 16:25:12

标签: xml perl xml-libxml

我有一个类似于此的XML模板(摘录):

<isSomething>_xxx_</isSomething>
<someValue>_xxx_</someValue>

我的代码正在通过模板并分别使用XML :: LibXML的findnode和setData方法替换 _xxx _ 占位符。

最后它看起来像这样:

<isSomething>true</isSomething>
<someValue>123.45</someValue>

这可以完成这项工作,但是如果isSomething标签看起来像这样,收件人系统会更加满意:

<isSomething/>

如果它是假的,将被完全省略。 有没有办法用XML :: LibXML做到这一点,还是应该在字符串输出上应用强大的正则表达式功能?

2 个答案:

答案 0 :(得分:5)

要删除节点,请使用removeChild。要生成空元素,请删除其文本子元素:

#! /usr/bin/perl
use warnings;
use strict;

use XML::LibXML;

my $xml = 'XML::LibXML'->load_xml( string => << '__XML__');
<root>
  <node id="a">
    <isSomething>_xxx_</isSomething>
    <someValue>_xxx_</someValue>
  </node>
  <node id="b">
    <isSomething>_xxx_</isSomething>
    <someValue>_xxx_</someValue>
  </node>
</root>
__XML__

my %nodes = ( a => [ 'true',  1 ],
              b => [ 'false', 2 ],
            );

for my $node ($xml->documentElement->findnodes('//node')) {
    my $id = $node->{id};
    my ($is_something, $value) = @{ $nodes{$id} };

    my ($s) = $node->findnodes('isSomething[.="_xxx_"]');
    if ('true' eq $is_something) {
        my ($text) = $s->findnodes('text()');
        $s->removeChild($text);
    } else {
        $node->removeChild($s);
    }

    my ($v) = $node->findnodes('someValue/text()[.="_xxx_"]');
    $v->setData($value);
}
print $xml;

答案 1 :(得分:4)

首先 - 请不要正确使用XML。这个不干净。 RegEx match open tags except XHTML self-contained tags

我认为你想要的是LibXML::XML::Element - 具体来说:

  

$node = XML::LibXML::Element->new( $name );
  

此函数创建一个未绑定到任何DOM的新节点。

其次是:

$node->replaceNode($newNode);

XML::LibXML::Node