2.2. The import element

An import element information item (referred to in this specification as an import element) is an element in the CellML namespace with a local name equal to import, which appears as a child of a model element.

  1. Every import element MUST contain an attribute in the namespace http://www.w3.org/1999/xlink, with a local name equal to href.

    1. The value of this attribute SHALL be a valid locator href, as defined in Section 5.4 of the XLink specification [6].

    2. The href attribute SHALL be treated according to the XLink specification [6], by applying the rules for simple-type elements.

    3. When describing an import element or one of its children, the phrase “imported CellML infoset” SHALL refer to the CellML infoset obtained by parsing the document referenced by the href attribute.

See more

At present the location specified by the href attribute must be a locally available file (not online). The path may either be absolute from the root directory, or relative to the importing model’s location.

For example, here’s a model based around casting for The Wizard of Oz. In the main model (the one doing the importing), the component used to play Dorothy is defined by importing a component named judy_garland from the file called role_of_dorothy.cellml and setting its reference in the main file to be the component named dorothy.

Note the file structure: the path to the imported file is specified relative to the importing file, in this case role_of_dorothy.cellml sits inside a folder called characters.

oz_model.cellml

<model name="oz">
  <import xlink:href="characters/role_of_dorothy.cellml">
          <component name="dorothy" component_ref="judy_garland" />
  </import>
  ...
</model>

characters/dorothy.cellml

<model name="candidates_for_dorothy">
  <component name="judy_garland"> ... </component>
  ...
  <import xlink:href="toto.cellml">
          <component name="judy_garlands_dog" component_ref="a_terrier_called_terry"/>
  </import>
</model>

characters/role_of_toto.cellml

<model name="candidates_for_toto">
  <component name="a_terrier_called_terry"> ... </component>
  <component name="scooby_doo"> ... </component>
</model>

The component representing Toto could be imported in one of two ways, both giving identical model representations. Either directly from the role_of_toto.cellml file, or indirectly via the role_of_dorothy.cellml file:

<model name="oz">
  <import xlink:href="characters/role_of_dorothy.cellml">
          <component name="dorothy" component_ref="judy_garland" />
  </import>

  <!-- Either directly from the "role_of_toto.cellml" file ... -->
  <import xlink:href="characters/role_of_toto.cellml">
          <component name="toto" component_ref="a_terrier_called_terry" />
  </import>

  <!-- ... OR indirectly through the role_of_dorothy.cellml" file. -->
  <import xlink:href="characters/role_of_dorothy.cellml">
          <component name="toto" component_ref="judy_garlands_dog" />
  </import>
</model>
  1. Every import element MAY contain one or more specific element children, each of which MUST be of one of the following types:

    1. An import component element; or

    2. An import units element.

See more

The only items which can be imported directly are component and units items. The intention is that these are modular building blocks, able to be passed between models easily through this import functionality.

When you import a component, all its variables and encapsulated child component items are imported too, along with any its governing math block and any units items it uses.

When you import a units item, the child unit items which it contain are imported as well.

  1. Any CellML infoset imported, directly or indirectly, by the imported CellML infoset MUST NOT be semantically equivalent to the importing CellML infoset (see 1.2.3.3 regarding semantic equivalence).

See more

The intention behind this restriction is to prevent circular import definitions from occurring. Models are able to import twins, that is, component or units items which are identical in content but under different names. Models may not import themselves, because this would create an infinite loop of dependence.

For example, the first Olsen twins model below is permitted: the same component is imported twice under different names.

<model name="olsen_twins">
  <import xlink:href="twin_sister.cellml">
    <component name="mary_kate" component_ref="sister"/>
  </import>
  <import xlink:href="twin_sister.cellml">
    <component name="ashley" component_ref="sister"/>
  </import>
<model>

This recursive import is not permitted because a component cannot import itself:

<!-- In a file called "multiplicity.cellml": -->
<model name="multiplicity">
  <import xlink:href="multiplicity.cellml">
   <component name="doug" component_ref="doug"/>
  </import>
<model>

The sames applies for “indirect” imports, where recursion is created over several files:

<!-- In a file called "multiplicity.cellml": -->
<model name="multiplicity">
  <import xlink:href="clone.cellml">
    <component name="doug" component_ref="clone"/>
  </import>
<model>

<!-- In a file called "clone.cellml": -->
<model name="first_clone">
  <import xlink:href="clone_of_clone.cellml">
    <component name="clone" component_ref="another_clone"/>
  </import>
</model>

<!-- In a file called "clone_of_clone.cellml": -->
<model name="repeating_cloning">
  <import xlink:href="multiplicity.cellml">
    <component name="another_clone" component_ref="doug"/>
  </import>
</model>