仅在特定条件为真时自动增量

时间:2014-03-05 20:25:19

标签: xml perl

我正在处理.xml文件,我需要一个perl脚本。我会尽力解释。我的输入格式如下:

<p t="opener">
  <w id="23">
    <o>Hi</o>
  </w>
  <w id="24">
    <o>world</o>
  </w>
</p>

也就是说,每个单词(Hi,world)由一个标签(<o></o>)分隔,另外,它有一个相关的数字,它不是从1开始。这个编号显示为一个值标签<w></w>内的属性“id”。最后,有一个顶级(<p></p>)表示不同的段落。

我需要的输出必须具有以下格式:

<p t="opener">
  <w id="1">
    <o>Hi</o>
  </w>
  <w id="2">
    <o>world</o>
  </w>
</p>

即,与输入相同的格式,但从1开始获得相关编号

我想解决方案必须涉及自动增量运算符(++),但事情变得更加困难,因为我需要应用从1开始的相关编号,只要段落具有属性“opener”(喜欢输入)

换句话说,我需要的是一个从1开始打印所需编号的条件,以防段落是“开场白”。我的建议是:

use warnings;
use strict;

$/ = undef
my $numbering = 0;
my $autonumbering = $numbering++;
my $filename      = shift;

open F, $filename or die "Usa: $0 FILENAME\n";
while (<F>) {
  if (/<p t=\"opener\".*?<\/p>/s) {
    # If the paragraph is <p t="opener"></p> (the dot (.) stands for every character, including \n)
    s/<w id=\".*?\"/<w id=\"$autonumbering\"/ge # replace the value of "id" by the variable $autonumbering
  }
}
close F;

我知道,实际上,我并没有告诉Perl仅在所需段落中应用替换。如果条件为真,我只是告诉将替换应用于整个文件,不是吗?

有任何建议可以帮助我应用限制并优化我的提案吗?

1 个答案:

答案 0 :(得分:4)

在没有使用专用XML库的情况下,我从未见过处理XML数据的好借口。

此程序使用XML::LibXML并且似​​乎按照您的要求执行。

将来请在编译程序之前不要放弃并寻求免费帮助。

use strict;
use warnings;

use XML::LibXML;

my $doc = XML::LibXML->load_xml(location => 'my.xml');

my $id;

for my $w_element ($doc->findnodes('//p[@t="opener"]/w[@id]')) {
  $w_element->setAttribute('id', ++$id);
}

print $doc->toString;

<强>输出

<?xml version="1.0"?>
<p t="opener">
  <w id="1">
    <o>Hi</o>
  </w>
  <w id="2">
    <o>world</o>
  </w>
</p>