我的文件如下:
<MAIN>
<SUB_MAIN>one</SUB_MAIN>
<VER>version#</VER>
(OTHER STUFF...)
<LOCATION>PATH</LOCATION>
</MAIN>
<MAIN>
<SUB_MAIN>two</SUB_MAIN>
<VER>version#</VER>
(OTHER STUFF...)
<LOC>PATH</LOC>
</MAIN>
我想要做的是搜索SUB_MAIN
的值,让我们说一个,如果找到它,则查找LOCATION
的值。转到该位置执行某些同步从中获取新版本并更新VER
信息。
我当前的代码有三个循环并且很难看。骨架是这样的:
$value = "one|two|three";
# for each line in file
while ($line < @FileDat) {
# see if it is a sub module?
if ( $line =~ /\<SUB_MAIN\>$value\<\/SUB_MAIN\>/ )
{
$found_it = 0;
while (!$found_it)
{
$lineNum++;
if ( $FileDat[$lineNum] =~ /\<VER\>\d+\<\/VER\>/ )
{
$currIndex = $lineNum;
while(1)
{
$lineNum++;
if ( $FileDat[$lineNum] =~ /\<LOC\>(.+)\<\/LOC\>/ )
{ #DO SOME STUFF...
$found_it = 1;
last;
}
}
#replace version #
$FileDat[$currIndex] = " <VER>$latestChangeList</VER>\n";
}
}
}
$lineNum++;
}
# write the modified array to new file
print NEWCFGFILEPTR @FileDat;
close(OPEN_FILES);
我怎样才能做得更好?
谢谢。
答案 0 :(得分:1)
使用XML::Simple。没有必要重新发明轮子,除非你打算让它变得更好,我非常怀疑这是你的任务。
答案 1 :(得分:1)
实际上,使用XML解析器比仅使用XML模块要复杂一些,因为你所拥有的并不是格式良好的XML。格式良好的XML文件将具有单个根,因此所有MAIN元素都将包含在单个元素中。
有一种相对简单的伪造方法,即将您的文件(在XML实体中引用)包装在适当的高级元素中。
另外,在你的示例数据中,第一个MAIN中有一个LOCATION元素,第二个MAIN中有一个LOC元素,我认为它是一个cut'n粘贴错误。
这是一种使用XML :: Twig的方法,它可以处理任何大小的输入文件(包括大到适合内存),并输出到标准输出。
#!/usr/bin/perl
use strict;
use warnings;
use XML::Twig;
binmode( STDOUT, ':utf8'); # if your input file is in UTF-8
my $file= shift @ARGV;
# wrap the content of the file in <data>...</data> so it becomes well-formed XML
my $xml= qq{<?xml version="1.0"?>
<!DOCTYPE data [ <!ENTITY file SYSTEM "$file">]>
<data>&file;</data>
};
XML::Twig->new( twig_handlers => { MAIN => \&main },
keep_spaces => 1,
)
->parse( $xml);
exit;
sub main
{ my( $t, $main)= @_;
my $location= $main->field( 'LOCATION');
$main->set_field( VER => get_version( $location));
$main->print;
$main->purge; # if the file is big and you want to free the memory
}
sub get_version
{ my( $location)= @_;
return "new.version.$location"; # the real code might be different!
}
如果输入文件不是UTF-8,则可能需要更改包装器以将正确的编码添加到XML声明中。如果使用的是纯ASCII,那么你就是好的(如果添加了UTF-8字符,它仍然可以工作)。
如果您不想使用XML :: Twig,则相同的技术适用于创建可由XML :: Simple或您要使用的任何其他模块读取的正确XML。
答案 2 :(得分:0)
您有一个XML文件。不要使用正则表达式(通常被认为是坏主意)解析它,而是尝试使用现有的XML解析模块之一,如XML::Parser。还有许多其他类似的模块,您可以通过searching for xml
on search.cpan.org找到它,但这是一个很好的模块。