1

例如,我想在 EMF 中建模一个 word 文档:

这将是我的元模型:

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 中的这个问题?

4

2 回答 2

2

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

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

所以,我创建了一个最小的元模型,它展示了 a 如何Document包含TableParagraph实例的混合。

在此处输入图像描述

诀窍是所有实例实际上都位于elements属性中(EFeatureMapEntry 数据类型)。然后,tablesparagraphs引用只是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>
于 2014-11-12T17:03:59.043 回答
0

在我看来,子引用的顺序只在持久模型中很重要。但是,由于模型是您的 word 文档的抽象,它的持久模型不一定代表它所抽象的内容。如果您想按顺序排列表格和段落,则只需添加一个 order 属性并为每个相关元素设置其值。

于 2014-09-16T14:06:15.347 回答