Perl - XML / HoH中的循环依赖性检查

时间:2013-04-02 10:58:08

标签: xml perl graph circular-dependency

我正在尝试使用示例工作流定义构建批处理/工作流脚本,如下所示。

<project id="1" name="Project One" desc="" status="">
    <module id="11" name="Module Eleven" desc="" status="">
        <group id="101" name="Group 101" desc ="" status="" skip="false">
            <task id="1001" type="Shell" priority="10" desc="" author="" added="" modified="" status="" skip="false">
                <predecessors ref="1002" />
                <program folder="." object="test.pl" />
                <arguments value="job1 10 0" />
            </task>
            <task id="1002" type="Shell" priority="10" desc="" author="" added="" modified="" status="" skip="false">
                <predecessors ref="1003" />
                <program folder="." object="test.pl" />
                <arguments value="job2 5 0" />
            </task>
            <task id="1003" type="Shell" priority="10" desc="" author="" added="" modified="" status="" skip="false">
                <predecessors ref="1001" />
                <program folder="." object="test.pl" />
                <arguments value="job3 15 0" />
            </task>
        </group>
    </module>
</project>

我使用XML :: Simple将XML转换为哈希哈希值。

我正在寻找一种有效的逻辑来检测XML或HoH中的循环依赖。

谢谢!

1 个答案:

答案 0 :(得分:5)

use Graph       qw( );
use XML::LibXML qw( );

my ($xml_qfn) = @ARGV
   or die "usage\n";

my $parser = XML::LibXML->new();
my $doc = $parser->parse_file($xml_qfn);

my %seen_task_ids;
my $task_dep_graph = Graph->new();

for my $task_node ($doc->findnodes('/project/module/group/task')) {
   my $id = $task_node->getAttribute('id');
   die("Duplicate task id $id\n") if $seen_task_ids{$id}++;

   my @deps =
      map $_->getAttribute('ref'),
       $task_node->findnodes('predecessors');

   $task_dep_graph->add_edge($id, $_) for @deps;
}

if (my @cycle = $task_dep_graph->find_a_cycle()) {
   die("Task dependency cycle @cycle\n");
}