在Perl中比较XML中的字符串?

时间:2015-07-16 16:55:30

标签: xml string perl comparison

完全免责声明:我对Perl来说是全新的,一周或更少的经验。在工作中,我当前的项目涉及一个过程,在该过程中我们从各个机构获取表示课程目录的XML文件,并将它们连接成一个文件。我有一个正常工作的Perl脚本+模块,它可以做到这一点;但是,我希望通过检查合并文件是否满足以下条件来添加一些额外的功能:

1)每个班级列表来自同一个学期(这包含在标签中)

2)每个班级列表都来自同一年(这包含在标签中)

这是我在合并后运行的当前子例程(其含义是问题肯定在下面的代码中):

sub check_files {
    my ($self, $file) = @_;
    my $parser;
    my $parsed;
    my @semesters;
    my @years;
    my $answer = 0;
    my $correct = 0;

    $parser = XML::LibXML->new;
    $parsed = $parser->parse_file($file);

    @semesters = $parsed->getElementsByTagName("SEMESTER");
    @years = $parsed->getElementsByTagName("YEAR");

    foreach my $semester1 (@semesters) {        
        my $semester2 = $semesters[1];

        if($semester1 ne $semester2) {
            if($semester1 ne "<SEMESTER>Do not delete this row</SEMESTER>") {
                print "Check semesters in data! $semester1 $semester2 \n\n";
                $answer += 1;
            }
        } else {
            print "Equal strings: $semester1 $semester2 \n\n";
            $correct += 1;
        }
    }

    foreach my $year1 (@years) {
        my $year2 = $years[1];

        if($year1 ne $year2) {
            if($year1 ne "<YEAR>Do not delete this row</YEAR>") {
                print "Check years in data! $year1 $year2 \n\n";
                $answer += 1;
            }           
        } else {
            print "Equal strings: $year1 $year2 \n\n";
            $correct += 1;
        }
    }

    print "Errors: $answer Correct: $correct \n\n";
    return $answer;

}

我针对元素1检查所有内容而不是0,因为连接的第一个文件是标题行(应该等于“不要删除此行”)。因此,“不要删除”的东西应该始终是元素0。

我在控制台中获得了很多“在数据中检查学期!2013 2013”​​的行。事实上,我的$正确变量增量的唯一时间是标题行如果条件失败。这让我觉得字符串比较会以某种方式搞砸了;我能想到的唯一解释是指针问题和编码。但是,我上周刚刚开始使用Perl,所以我真的不知道我在说什么。我知道我的代码也不优雅,对此很抱歉。

感谢任何可以提供帮助的人,甚至是阅读此内容并决定不这样做的人。

1 个答案:

答案 0 :(得分:0)

根据您显示的数据运行代码时,我没有获得您描述的输出,但我确实为您提供了解决方案

您真的需要了解XML数据。它的嵌套非常类似于函数式编程语言,因此标记必须是平衡的,并且总是有一个根节点。在您的数据中,它被称为<ROOT>,如果您在文件的末尾看起来就会有一个结束</ROOT>

此代码的工作原理是使用XPath表达式查找除第一个SECTION元素之外的所有元素,然后从每个元素中提取YEARSEMESTER个子元素的值并保持几个哈希的记录

如果找到多年或多个学期,我不知道您希望子程序做什么,所以这一切都打印了几行摘要。我希望你能从这里了解如何继续

sub check_files2 {
    my $self = shift;
    my ($file) = @_;

    my $doc = XML::LibXML->load_xml(location => $file);

    my @sections = $doc->findnodes('/ROOT/SECTION[position() > 1]');
    printf "%d sections found after the first\n", scalar @sections;

    my (%years, %semesters);

    for my $section ( @sections ) {
        my $year = $section->findvalue('YEAR');
        my $semester = $section->findvalue('SEMESTER');
        ++$semesters{$semester};
        ++$years{$year};
    }

    my @years = keys %years;
    printf "%d different years: %s\n", scalar @years, "@years";

    my @semesters = keys %semesters;
    printf "%d different semesters: %s\n", scalar @semesters, "@semesters";
}

输出

24 sections found after the first
1 different years: 2013
1 different semesters: F