Search code examples
pythonxmlscriptingenterprise-architect

How to correctly import a complete Enterprise Architect project from XMI by script?


Starting with a running instance of EA and an empty project opened (consisting only of an empty root node), I am trying to write a simple script to import a full EA project from a .xmi file. I know it can be done easily with the GUI but I need to use that functionality for another problem.

When I import a .xmi of an EA project with the GUI I get a message saying

'XMI contains a Model which may be placed at the root level in the Project Browser. Press Yes to import as Root Model, No to place under selected package'

and can choose to do this. (The .xmi file has been created by exporting a project from EA to .xmi)

When I run the script (see below) it seems to choose one of the options, depending on what I don't know. Mostly the one that puts the root node of the imported project under the already existing empty root. So the project structure is muddled.

Here's the script:

repo = eaApp.Repository
root = repo.Models[0]
projectInterface = repo.GetProjectInterface() 
newPkgGUID = projectInterface.ImportPackageXMI(root.PackageGUID, XMISourcePath, 1, 1) # actual import

What I basically want to do is I always want to put the root node of the imported project at root level, but there seems to be no access to the dialogue that pops up when operating from the GUI.

Any suggestions for this problem?

The script is written in Python.


Solution

  • I just tested this. In order to load the XMI you need to run

    newPkgGUID = projectInterface.ImportPackageXMI(root.PackageGUID, XMISourcePath, 1, 0)
    

    So Strip GUID is zero! That will replace the contents of your model without asking. Once done, the model in the browser is collapsed and you have everything replaced. You should be careful when doing that kind of things.

    Now if your import contains a root node you are forced to do some additional work. EA will place the root as a view under the empty new root. Not nice.

    As some work around you might first read your XMI and modify the root GUID in there to be the same of your new model. That GUID is (like e.g. in this export)

    <XMI.content>
        <UML:Model name="EA Model" xmi.id="MX_EAID_16B64057_C8E3_4697_A31B_3ABB87DB4D64">
            <UML:Namespace.ownedElement>
                <UML:Class name="EARootClass" xmi.id="EAID_11111111_5487_4080_A7F4_41526CB0AA00" isRoot="true" isLeaf="false" isAbstract="false"/>
                <UML:Package name="Model" xmi.id="EAPK_16B64057_C8E3_4697_A31B_3ABB87DB4D64" isRoot="true" isLeaf="false" isAbstract="false" visibility="public">
    

    that on the last line above (at the very beginning of your XMI). Using Python that's easy to do. You just need to create a temp file you can use in the later import. Also note that the format is different to the native EA GUID. So the original EA GUID would have been {16B64057-C8E3-4697-A31B-3ABB87DB4D64}.


    Old answer

    Bascially this is a half baked Sparx typical API. However, you need to look for the target GUID in the packages by issuing a query

    repository.SQLQuery("SELECT ea_guid FROM t_packages WHERE ea_guid = '%s'" % guid)
    

    If the result returns a row you know that the target alread exists and you have react accordingly. That means you have to import to the found package. You could as well make a

    p = repository.getPackageByGUID(guid) 
    

    in order to pinpoint the correct import package.

    What makes me wonder is that you use Strip GUID which in any case should create a new copy of the import irrelevant of where you put it. I think the dialog would not pop up with Strip GUIDs checked.

    N.B. Strip GUID means that EA will create new elements for anything. This is for creating copies (like patterns). In case you want to restore you must not turn on Strip GUID! That will EA make replace existing elements with that GUID (in fact it's a bit more complicated but basically that's it).