Xml 仅当特定条件为真时自动递增

Xml 仅当特定条件为真时自动递增,xml,perl,Xml,Perl,我正在处理.xml文件,需要一个perl脚本。我会尽我最大的努力解释。我的输入具有以下格式: <p t="opener"> <w id="23"> <o>Hi</o> </w> <w id="24"> <o>world</o> </w> </p> 你好 世界 也就是说,每个单词(Hi,world)由一个标签()分隔,此外,它还有一个不从1

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

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

你好 世界

也就是说,每个单词(Hi,world)由一个标签(
)分隔,此外,它还有一个不从1开始的相关数字。此编号显示为标签
内属性“id”的值。最后,还有一个顶层(

),表示不同的段落

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

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

你好 世界

也就是说,与输入格式相同,但从1开始获得相关编号

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

换句话说,我需要的是一个条件,即打印从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;
使用警告;
严格使用;
$/=未定义
我的$number=0;
my$autonumbering=$numbering++;
我的$filename=shift;
打开F$filename或死“Usa:$0 filename\n”;
而(){

if(/我从来没有看到过不使用专用XML库处理XML数据的好借口

此程序使用并似乎执行您要求的操作

在将来,请不要放弃,在你还没有得到你的程序编译之前寻求免费帮助

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>

你好 世界


我从未见过不使用专用XML库就处理XML数据的好借口

此程序使用并似乎执行您要求的操作

在将来,请不要放弃,在你还没有得到你的程序编译之前寻求免费帮助

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>

你好 世界


我建议不要尝试在一行中完成所有操作。在(我的$line=)的同时制作一个
{
循环并创建一个状态机。如果发现条件,从一开始就重新启动,或者创建一个
@current\u段落
变量,保存从

的当前行集。这样,您可以更容易地看到正在发生的情况并进行调试。此外,如果您有足够精确的文本使regexp like
/

-1){…

您是仅限于perl还是愿意使用XSLT解决方案?谢谢您的回答,abiessu。是的,我恐怕只限于perl。但我不知道那个索引函数。我正在学习如何使用它,并尝试将其应用到我的脚本中。谢谢!您有什么理由不为此使用适当的XML解析器吗?很可能会要使用正则表达式和条件,需要做更多的工作。您的Perl代码甚至无法编译。请有礼貌地自己尝试合理地解决这个问题。我建议不要尝试在一行中完成所有操作。在(my$line=)时做一个
while{
循环并创建一个状态机。如果发现条件,从一开始就重新启动,或者创建一个
@current\u段落
变量,保存从

的当前行集。这样,您可以更容易地看到正在发生的情况并进行调试。此外,如果您有足够精确的文本使regexp like
/

-1){…

您是仅限于perl还是愿意使用XSLT解决方案?谢谢您的回答,abiessu。是的,我恐怕只限于perl。但我不知道那个索引函数。我正在学习如何使用它,并尝试将其应用到我的脚本中。谢谢!您有什么理由不为此使用适当的XML解析器吗?很可能会在正则表达式和条件语句方面还有很多工作要做。您的Perl代码甚至无法编译。请有礼貌地亲自尝试解决这个问题。