我正在尝试使用示例工作流定义构建批处理/工作流脚本,如下所示。
<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中的循环依赖。
谢谢!
答案 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");
}