Perl-XML/HoH中的循环依赖性检查
我正试图用一个示例工作流定义构建一个批处理/工作流脚本,如下所示Perl-XML/HoH中的循环依赖性检查,xml,perl,graph,circular-dependency,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">
<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中的循环依赖关系
谢谢 您可以显示转换为散列的代码吗?
my$xml=newxml::Simple代码>my$data=$xml->XMLin($list)代码>我正在考虑遍历散列,将每个任务保存到字典中,并检查是否已经遇到密钥。这也有助于我实现一个逻辑来验证是否存在重复的任务id。任务是否总是有一个前置任务?如果不是,你如何表达?它是否有多个前置
元素,或者在ref
属性中有空格分隔的值,或者其他方式?任务可能有多个前置。可以在XML::SimpleMapzing中以列表的形式访问多个标记。你只是让事情变得简单多了。我有一种感觉,从我做的所有谷歌搜索中,图形是一种方式。我想我可能会使用graph模块构建其余的逻辑。此外,核心模块外的图形模块没有依赖关系。
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");
}