Xml 仅当特定条件为真时自动递增
我正在处理.xml文件,需要一个perl脚本。我会尽我最大的努力解释。我的输入具有以下格式: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
<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代码甚至无法编译。请有礼貌地亲自尝试解决这个问题。