EMF替代儿童参考

时间:2014-06-11 19:23:36

标签: document metafile

作为示例,我想在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中的这个问题吗?

2 个答案:

答案 0 :(得分:2)

这正是EMF中“特征地图”的用例。

您希望将多种类型的对象组合成一个有序列表,然后使用单独的引用访问各个类型。

因此,我创建了一个最小元模型,显示Document如何包含TableParagraph实例的混合。

enter image description here

诀窍是所有实例实际上都位于elements属性(EFeatureMapEntry数据类型)中。然后,tablesparagraphs引用只是elements容器的投影。 如下图所示,实例以正确的顺序存储。

enter image description here

正确设置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属性并为每个相关元素设置其值。