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 |
Amir Kanan 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 #1770345 is a reply to message #1770344] |
Thu, 10 August 2017 08:00 |
|
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 |
Amir Kanan 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 #1770899 is a reply to message #1770845] |
Fri, 18 August 2017 14:33 |
Amir Kanan 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 |
|
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
Kinori Tech
Need professional support for Epsilon, EMF?
Go to: https://kinori.tech
[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 #1771123 is a reply to message #1771104] |
Tue, 22 August 2017 09:07 |
Athanasios Zolotas Messages: 52 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 |
|
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):
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
|
|
| |
Goto Forum:
Current Time: Thu Sep 26 14:33:04 GMT 2024
Powered by FUDForum. Page generated in 0.05634 seconds
|