问题描述
我正在尝试使用 ATL 实现 M2M 转换。所以我正在将源模型 (1) 转换为目标模型 (2),我对 ATL 很陌生,我找不到任何关于如何启用多对多转换的文档。我想做的是: 转换(1)具有名为“操作”的类的源模型,它引用另一个名为“参数”的类,该引用名为“操作输入”,其基数为(0..n)到(2)具有名为的类的目标模型“function”,它引用另一个名为“Param”的类,引用名为“functionInput”,其基数为 (0..n)。 所以我写了以下 ATL 转换:
rule operation2Function {
from
s: Source!operation
to
t: Target!Function
(
functionInput<-s.operationInput)
}
然而,它似乎不起作用,因为基数是多对多的,所以我尝试了以下代码:
rule operation2Function {
from
s: Source!operation
to
t: Target!Function
(
functionInput<-Source!operation.allInstances() ->select(e | e.oclIsTypeOf(Source!operation)->collect(e| e.operationInput),)
}
即使我初始化了源元模型的一个实例,我仍然没有得到正确的结果。
我很感激您在如何启用多对多 ((0..n) 或 (1..n)) 转换方面的帮助。
解决方法
ATL 是一种声明性转换语言,因此您最好只指定必须发生的事情而不是如何发生,因此与其强制向下隧道以处理函数参数的多样性,只需编写一个单独的规则,将 1 个参数与 1 个操作输入相关联在参数的包含函数和操作输入的包含操作的上下文中。
如果你真的想强制转换,你可能更喜欢 QVTo。
(allInstances() 几乎总是错误的解决方案。最好的情况是效率低下,最坏的情况是能够使用许多错误的贡献。)