作为示例,我想在EMF中为单词文档建模:
这将是我的元模型:
document
- table (0..*)
- paragraph (0..*)
这里的问题是模型非常线性:
document
- table_1
- table_2
- table_3
- paragraph_1
不可能在两个表(table_1和table_2)之间插入一个段落。
我的解决方案是以另一种方式对元模型进行建模:
document
- (abstract) documentChild (0..*)
table inherit documentChild
paragraph inherit documentChild
这对我来说似乎不是最优的。还有另一种方法可以解决EMF中的这个问题吗?
答案 0 :(得分:2)
这正是EMF中“特征地图”的用例。
您希望将多种类型的对象组合成一个有序列表,然后使用单独的引用访问各个类型。
因此,我创建了一个最小元模型,显示Document
如何包含Table
和Paragraph
实例的混合。
诀窍是所有实例实际上都位于elements
属性(EFeatureMapEntry数据类型)中。然后,tables
和paragraphs
引用只是elements
容器的投影。
如下图所示,实例以正确的顺序存储。
正确设置EMF类的所有属性有点棘手。尤其
volatile="true"
transient="true"
derived="true"
containment="true"
因此,我在这里列出了元模型的完整XMI内容:
<?xml version="1.0" encoding="UTF-8"?>
<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="doc" nsURI="doc" nsPrefix="doc">
<eClassifiers xsi:type="ecore:EClass" name="Table">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Paragraph">
<eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
</eClassifiers>
<eClassifiers xsi:type="ecore:EClass" name="Document">
<eStructuralFeatures xsi:type="ecore:EReference" name="tables" ordered="false"
upperBound="-1" eType="#//Table" volatile="true" transient="true" derived="true"
containment="true">
<eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="group" value="#elements"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EReference" name="paragraphs" ordered="false"
upperBound="-1" eType="#//Paragraph" volatile="true" transient="true" derived="true"
containment="true">
<eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="group" value="#elements"/>
</eAnnotations>
</eStructuralFeatures>
<eStructuralFeatures xsi:type="ecore:EAttribute" name="elements" upperBound="-1"
eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EFeatureMapEntry">
<eAnnotations source="http:///org/eclipse/emf/ecore/util/ExtendedMetaData">
<details key="kind" value="group"/>
</eAnnotations>
</eStructuralFeatures>
</eClassifiers>
</ecore:EPackage>
答案 1 :(得分:0)
在我看来,子引用的顺序仅在持久模型中很重要。但是,由于模型是单词文档的抽象,因此其持久模型不一定代表它抽象的内容。如果要按顺序放置表和段落,则只需添加一个order属性并为每个相关元素设置其值。