Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » Epsilon » How to store all root elements in a variable using EOL?(EOL syntax for querying XML)
How to store all root elements in a variable using EOL? [message #1770077] Tue, 08 August 2017 07:39 Go to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi,

I am running a simple M2T transformation using EGX and EGL. I can generate 3 text files based on the source model (an XML file with 3 root elements). However, the EGX and EGL codes has been change to generate a single text file by looping through the list of elements (EGL code below). I am trying to query the root element (line 5: EGX code) of the xml file below:

<?xml version="1.0" encoding="ASCII"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.org/MetaModel" xsi:schemaLocation="http://www.example.org/MetaModel MetaModel.ecore">
<Person id="3" given_name1="Amir" last_name="Liu"/>
<Person id="1" given_name1="Amir" last_name="Geo"/>
<Person id="2" given_name1="Geo" last_name="Liu"/>
</xmi:XMI>

Using the following EGX code :

1 rule R1
2 transform Person : Person {
3 parameters{
4 // Get all <Person> elements
5 var people = Person.all;
6 }
7 template : "file.egl"
8
9 target : "doc/Person.txt"
10 }

Using following EGL template:

[%for (p in people) {%]
"_": {
"id": "[%=p.id%]",
"pro": [
{
"ele": "person"
},
{
"given_name1": "[%=p.given_name1%]"
},
{
"last_name": "[%=p.last_name%]"
}
]
}

[%}%]


How to store all "Person" elements (root elements) into People (a variable) using EOL ?

Many thanks,
Amir

[Updated on: Tue, 08 August 2017 08:01]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1770085 is a reply to message #1770077] Tue, 08 August 2017 08:58 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 1611
Registered: July 2009
Location: York, UK
Senior Member

Hi Amir,

for (p in Person.all) should do the trick.

Cheers,
Dimitris
Re: How to store all root elements in a variable using EOL? [message #1770122 is a reply to message #1770085] Tue, 08 August 2017 14:04 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Dimitris,

Thanks for your quick reply.

I have already tried that but I got the following exception:

Exception in thread "main" Property 'all' not found in object org.eclipse.emf.ecore.impl.DynamicEObjectImpl@1451ef4e [eClass: org.eclipse.emf.ecore.impl.EClassImpl@19c8ef56 [name: Person] [instanceClassName: null] [abstract: false, interface: false]]
at (/template/file.egl@1:12-1:22)
.....
......
What this means?
Thanks for your time and support.
Cheers,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770123 is a reply to message #1770122] Tue, 08 August 2017 14:08 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 1611
Registered: July 2009
Location: York, UK
Senior Member

You should change

transform Person : Person {

to

transform person : Person {

as in its current form the "Person" variable shadows the "Person" type.

Cheers,
Dimitris
Re: How to store all root elements in a variable using EOL? [message #1770344 is a reply to message #1770123] Thu, 10 August 2017 07:55 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Dimitris,

Thanks,. It is working now. However, I have changed the logic as below:

-- My code is similar to the App.Java of org.eclipse.epsilon.examples.egl.library

--Managed the coordination logic using only EGL files but now EGX and EGL files

--Switched module = new EglTemplateFactoryModuleAdapter(new EglTemplateFactory());
with
module = new EglTemplateFactoryModuleAdapter(new EglFileGeneratingTemplateFactory());

Should I use EGX for calling a template from the other template?
How can I manage nested templates using EglTemplateFactory?


Many thanks,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770345 is a reply to message #1770344] Thu, 10 August 2017 08:00 Go to previous messageGo to next message
Dimitris Kolovos is currently offline Dimitris KolovosFriend
Messages: 1611
Registered: July 2009
Location: York, UK
Senior Member

Hi Amir,

> Should I use EGX for calling a template from the other template?

Both EGX and EGL can be used to call other templates but EGX is the recommended option.

> How can I manage nested templates using EglTemplateFactory?

I'm not sure I understand your question. Could you please elaborate a bit more?

Cheers,
Dimitris
Re: How to store all root elements in a variable using EOL? [message #1770684 is a reply to message #1770345] Wed, 16 August 2017 08:49 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Dimitris,

Thanks for your support, I have found the answer of my second question in the Epsilon Book . I should use @Template Operations to manage nested templates.

I have other question related to the same thread as below:
First, I try to give you a background then I ask my question.


Using following EGL template
, I can get the element (id, given_name and last_name) values :

[%for (p in Person.all) {%]
{
"id": "[%=p.id%]"
},
{
"ele": "person"
},
{
"given_name1": "[%=p.given_name1%]"
},
{
"last_name": "[%=p.last_name%]"
}
]
}

[%}%]

based on the following model:

<?xml version="1.0" encoding="ASCII"?>
<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.example.org/MetaModel" xsi:schemaLocation="http://www.example.org/MetaModel MetaModel.ecore">
<Person id="3" given_name1="Amir" last_name="Liu"/>
<Person id="1" given_name1="Amir" last_name="Geo"/>
<Person id="2" given_name1="Geo" last_name="Liu"/>
</xmi:XMI>

How can I retrieve the type (Person) elements (Id, given_name and last_name) ?
Currently, It is hard coded. However, I would like to get the collection of them from "p".

The following EOL test:
[%for (p in Person.all) {%]
[%for (element in p) {%]
[%=element.println()%]
[%}%]
[%}%]

prints the following:

org.eclipse.emf.ecore.impl.EClassImpl@6c5b675e (name: Person) (instanceClassName: null) (abstract: false, interface: false)

Many thanks,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770792 is a reply to message #1770684] Thu, 17 August 2017 07:24 Go to previous messageGo to next message
Thanos Zolotas is currently offline Thanos ZolotasFriend
Messages: 49
Registered: November 2016
Location: York
Member
Amir Kanan wrote on Wed, 16 August 2017 08:49

How can I retrieve the type (Person) elements (Id, given_name and last_name) ?
Currently, It is hard coded. However, I would like to get the collection of them from "p".

The following EOL test:
[%for (p in Person.all) {%]
[%for (element in p) {%]
[%=element.println()%]
[%}%]
[%}%]

prints the following:

org.eclipse.emf.ecore.impl.EClassImpl@6c5b675e (name: Person) (instanceClassName: null) (abstract: false, interface: false)

Many thanks,
Amir


Hi Amir,

I am not quite sure I understand what exactly you would like to print. Could you please elaborate a little bit more?

Regards,
Thanos
Re: How to store all root elements in a variable using EOL? [message #1770797 is a reply to message #1770792] Thu, 17 August 2017 07:48 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Thanos,

Thanks for your reply.

If my model contains an element in the following format (a person with three attributes):

<Person id="1" given_name1="Amir" last_name="Geo"/> => <element-name attribute1-label = attribute1-value attribute2-label = attribute2-vakye />

How can I print / store attribute labels (eg id, given_name1 and last_name) ?

Many thanks,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770829 is a reply to message #1770797] Thu, 17 August 2017 13:14 Go to previous messageGo to next message
Thanos Zolotas is currently offline Thanos ZolotasFriend
Messages: 49
Registered: November 2016
Location: York
Member
Hi Amir,

Can you please try the following:

for (p in Person.all) {
    for (anAttribute in p.eClass.eAllAttributes) {
            anAttribute.name.println();
    }
}


In case you don't want to get the attributes inherited by parent classes then you just replace eAllAttributes with eAttributes.

Hope this helps.

Regards,
Thanos

[Updated on: Fri, 18 August 2017 08:11]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1770844 is a reply to message #1770829] Thu, 17 August 2017 14:33 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Thanos,

You made my day. It is working fine. However, I have down the following changes:

for (p in Person.all) {
    for (anAttribute in p.eClass.eAllAttributes) {
            anAttribute.name.println();
    }
}


I will get an error If I use:

p.eClass().eAllAttributes() 


I would be grateful if you advice a tutorial where I can get better understanding of the problem I had.

I tried to search in the documentation and the forum and don't seem to be able to find any information on this matter.

Do you recommend reading more on OCL or EOL or EMF based models ?!

Many thanks,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770845 is a reply to message #1770844] Thu, 17 August 2017 15:00 Go to previous messageGo to next message
Thanos Zolotas is currently offline Thanos ZolotasFriend
Messages: 49
Registered: November 2016
Location: York
Member
Hi Amir,

Glad this helped. Yes you're right, you don't need the parentheses.

Quote:
I would be grateful if you advice a tutorial where I can get better understanding of the problem I had.


This tutorial [1] is a good one. You can also take a look at Lars Vogel tutorial on EMF [2]. Both help getting a basic understanding of EMF.

Quote:
Do you recommend reading more on OCL or EOL or EMF based models ?!


Well, regarding EMF, there's the "EMF: Eclipse Modelling Framework book" [3] which is the definitive guide for EMF. You will find answers to most of your problems with EMF in there. I also find quite handy to take a quick look at the EMF metamodel [4] when I deal with EMF based models. For example in this case, the answer was there: as any type is basically an EClass, you can navigate in the metamodel using the references/attributes to reach the feature you're looking for.

I guess that you'are already familiar with the Epsilon Book [5] and the Epsilon website [6] which also has some good examples.

And of course you can always ask questions on this forum - we are glad to help.

[1]: https://eclipsesource.com/blogs/tutorials/emf-tutorial/
[2]: http://www.vogella.com/tutorials/EclipseEMF/article.html#example-define-a-new-emf-models
[3]: http://www.informit.com/store/emf-eclipse-modeling-framework-9780321331885
[4]: http://www.kermeta.org/docs/org.kermeta.ecore.documentation/build/html.chunked/Ecore-MDK/Ecore-MDK_figures/EcoreMainView.png
[5]: https://www.eclipse.org/epsilon/doc/book/
[6]: https://www.eclipse.org/epsilon/examples/

[Updated on: Thu, 17 August 2017 15:01]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1770899 is a reply to message #1770845] Fri, 18 August 2017 14:33 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Thanos,


Using

for (p in Person.all) {
    for (anAttribute in p.eClass.eAllAttributes) {
            anAttribute.name.println();
    }
}



I have retrieved values, which were not consistent with my model. For example, with

<Person id="1" given_name1="Amir" last_name="Geo"/>
<Person  given_name1="Geo222" />


I have got the following:

id=1,  given_name1= Amir,  last_name=Geo
id=,  given_name1= Geo222,  last_name=


As you can see, there are two elements (person), which second one did not have attributes "id" and "last_name".
I believe, I am reading from the meta-model (below) but not model.

<?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="domainMetaModel" nsURI="http://www.example.org/domainMetaModel"
    nsPrefix="">
  <eClassifiers xsi:type="ecore:EClass" name="Person">
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="id" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="last_name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
    <eStructuralFeatures xsi:type="ecore:EAttribute" name="given_name1" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
  </eClassifiers>
  <eClassifiers xsi:type="ecore:EClass" name="Source">
    <eStructuralFeatures xsi:type="ecore:EReference" name="persons" upperBound="-1"
        eType="#//Person" containment="true"/>
  </eClassifiers>
</ecore:EPackage>


However, I wanted to read from my model that conform to above meta-model.

Do you have any idea?

Regards,
Amir
Re: How to store all root elements in a variable using EOL? [message #1770915 is a reply to message #1770899] Fri, 18 August 2017 17:55 Go to previous messageGo to next message
Horacio Hoyos is currently offline Horacio HoyosFriend
Messages: 198
Registered: October 2009
Location: UK
Senior Member

Hi Amir,

The output seems consistent with the model, not the metamodel. Can you share your models and EGL/EGX scripts?

I think that what you want to do is to get the attribute name from the metamodel and then the attribute value from the model element. IMHO, since EGL templates are usually for a specific meta model it is OK to have the attribute names hard-coded into the code:
(PersonTemplate.egl)
// This is a generated file
Person:
    id = [%=p.id%],
    given_name1 = [%=p. given_name1%],
    last_name = [%=p. given_name1%]


Invoked from EGX:
(PersonGenerator.egx)
Quote:

rule Person2File
transform p : Person {

// The EGL template to be invoked
template : "PersonTemplate.egl"

// Output file
target : p.id + ".txt"

}


Note that in this scenario you will create one file per person. That is, the EGX rule will be invoked once per person in your model. The name of the variable of the rule (the one after transform) is automatically passed to the EGL template, hence I can reference it directly.

If you want all persons in a single file you need to either have another class that contains persons or use EGL alone, or like in your initial example pass the "Persons.all" collection... however you will generate the file the same number of times as Persons... not ideal (e.g. if your model has 1000 persons you will create the same file 1000 times).

I can think of a couple of ways to make the "generic" method work in which the template can print information from an arbitrary metamodel... but still the EGX rules will need a specific metamodel type/class.

Perhaps if you elaborate more on what you want to achieve we can guide you better. Are you trying to create a JSON version of your model? If so perhaps an ETL transformation will suite you better with the JSON driver for the output model. The JSON driver can be found in the epsilon repository in GitHub[1].

Cheers,

[1]https://github.com/epsilonlabs


Horacio Hoyos Rodriguez
Epsilon Committer
Research Assistant
University Of York

[Updated on: Fri, 18 August 2017 17:56]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1771104 is a reply to message #1770915] Tue, 22 August 2017 01:51 Go to previous messageGo to next message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Hoyos,

Thanks for your support and time.
So lets switch to ETL with the JSON driver for the output model.

I have checked the repository and found EMC-JSON. I believe, it designed to load the (JSON) source model but not loading an EMF model in order to produce JSON (output model).

JsonModel model = new JsonModel();
		model.setName("M");
		model.setFile(new File("commits.json"));
		model.load();


Would you please advise how can I adapt it to transform and EMF model to JSON?

Regards,
Amir
Re: How to store all root elements in a variable using EOL? [message #1771123 is a reply to message #1771104] Tue, 22 August 2017 09:07 Go to previous messageGo to next message
Thanos Zolotas is currently offline Thanos ZolotasFriend
Messages: 49
Registered: November 2016
Location: York
Member
Hi Amir,

Regarding your question on reading from the metamodel instead of the model, I don't think that this is the case. The printed results are consistent with your model. In EMF, every model has to conform to its metamodel, thus any element has all the attributes of its type instantiated. That means, that even if a Person element hasn't got its name attribute set, the attribute is instantiated. If I understand correctly your problem and the desired output, you can just avoid printing the labels of the attributes that are empty and print only those that have a value.

Regarding the JSON approach that Horacio suggested, I haven't used the driver in the past so I am not sure how to make it work.

Hope this helps,
Thanos

[Updated on: Tue, 22 August 2017 09:19]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1771124 is a reply to message #1771123] Tue, 22 August 2017 09:24 Go to previous messageGo to next message
Antonio Garcia-Dominguez is currently offline Antonio Garcia-DominguezFriend
Messages: 476
Registered: January 2010
Senior Member
The EMC JSON driver is work-in-progress at the moment - hopefully it shouldn't change much, but it's hard to guarantee things this early. It's more convenient to use it to manipulate existing JSON files than to create new JSON files. If you are creating a JSON model from scratch, you'll need to invoke M.setRoot(...) with an appropriate JSONArray or JSONObject instance.

To navigate a file, you could use the snippet you mentioned to load the model and then access things like this, assuming your JSON looks like '[{name: "foo"}]' (so the root is a JSONArray with one JSONObject inside):

M.root[0].e_child.a_name


To make changes, the EMC JSON driver does not have a property setter yet, so you can't assign things to x.a_name, for instance, but you can still invoke the methods in the SimpleJSON 1.1.1 JSONObject and JSONArray classes as usual. These work like HashMaps and ArrayLists, basically:

http://juliusdavies.ca/json-simple-1.1.1-javadocs/org/json/simple/package-summary.html

After you're done, you can invoke the store(...) method on the JsonModel to save any changes.

Let us know how it goes!

[Updated on: Tue, 22 August 2017 09:27]

Report message to a moderator

Re: How to store all root elements in a variable using EOL? [message #1771917 is a reply to message #1771124] Fri, 01 September 2017 05:52 Go to previous message
Amir Kanan is currently offline Amir KananFriend
Messages: 22
Registered: July 2017
Junior Member
Hi Antonio, Thanos and Horaclo

Thanks for all your supports. My code is working fine.

Regards,
Amir
Previous Topic:eol standalone failed to run native types
Next Topic:passing arguments from Java to EOL
Goto Forum:
  


Current Time: Wed Nov 14 21:23:57 GMT 2018

Powered by FUDForum. Page generated in 0.02708 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top