Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » M2T (model-to-text transformation) » <c:iterate> over elements
<c:iterate> over elements [message #60980] Tue, 12 May 2009 09:41 Go to next message
Eclipse UserFriend
Originally posted by: nickmari77.yahoo.com

Hi Paul,

I have this (part of a) model generated with emf:

<EnumVarTypeData some attributes...">
<allInfos Name="InfoA" other attributes.../>
<allInfos Name="InfoB" other attributes.../>
<allLanguage Type="TypeA" other attributes..."/>
<allLanguage Type="TypeB" other attributes.../>
<allEnumValues>ValA</allEnumValues>
<allEnumValues>ValB</allEnumValues>
<allEnumValues>ValC</allEnumValues>
<allEnumValues>ValD</allEnumValues>
</EnumVarTypeData>

where allEnumValues are serialized as elements.

I can iterate through allInfos and allLanguage with
this a normal iterate tag:

<c:iterate select="$root/allInfos" var="info">

But, how do I iterate allEnumValues? And how do I access ValA, ValB, ...
since allEnumValues doesn't have attributes?

I've found that I can access the first allEnumValues with:

<c:get select="$root/@allEnumValues"/>

and it returns me ValA. But I still miss all the others.


Thank you for your support :)

Nick
Re: <c:iterate> over elements [message #61028 is a reply to message #60980] Tue, 12 May 2009 12:10 Go to previous messageGo to next message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Nick Mari wrote:
> Hi Paul,
>
> I have this (part of a) model generated with emf:
>
> <EnumVarTypeData some attributes...">
> <allInfos Name="InfoA" other attributes.../>
> <allInfos Name="InfoB" other attributes.../>
> <allLanguage Type="TypeA" other attributes..."/>
> <allLanguage Type="TypeB" other attributes.../>
> <allEnumValues>ValA</allEnumValues>
> <allEnumValues>ValB</allEnumValues>
> <allEnumValues>ValC</allEnumValues>
> <allEnumValues>ValD</allEnumValues>
> </EnumVarTypeData>
>
> where allEnumValues are serialized as elements.

JET doesn't know how things are serialized. What counts is how things
are declared in the .ecore model. Is allEnumValues an EReference or an
EAttribute?

I suspect it is an EAttribute with an unbounded upperbound. The JET
XPath engine has a problem with such things because the XPath
information model doesn't consider the possibility of an attribute being
multi-valued. I haven't figured out a good way to handle this.

If you have control over your .ecore model, the easiest thing to do
would be to convert the multi-valued EAttribute into a multi-valued
EReference to a new type which has a single valued EnumValue? Make any
sense?

Paul
Re: <c:iterate> over elements [message #61075 is a reply to message #61028] Tue, 12 May 2009 13:05 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: nickmari77.yahoo.com

Paul Elder wrote:

> Nick Mari wrote:
>> Hi Paul,
>>
>> I have this (part of a) model generated with emf:
>>
>> <EnumVarTypeData some attributes...">
>> <allInfos Name="InfoA" other attributes.../>
>> <allInfos Name="InfoB" other attributes.../>
>> <allLanguage Type="TypeA" other attributes..."/>
>> <allLanguage Type="TypeB" other attributes.../>
>> <allEnumValues>ValA</allEnumValues>
>> <allEnumValues>ValB</allEnumValues>
>> <allEnumValues>ValC</allEnumValues>
>> <allEnumValues>ValD</allEnumValues>
>> </EnumVarTypeData>
>>
>> where allEnumValues are serialized as elements.
>
> JET doesn't know how things are serialized. What counts is how things
> are declared in the .ecore model. Is allEnumValues an EReference or an
> EAttribute?

It's an EAttribute

>
> I suspect it is an EAttribute with an unbounded upperbound. The JET
> XPath engine has a problem with such things because the XPath
> information model doesn't consider the possibility of an attribute being
> multi-valued. I haven't figured out a good way to handle this.
>
> If you have control over your .ecore model, the easiest thing to do
> would be to convert the multi-valued EAttribute into a multi-valued
> EReference to a new type which has a single valued EnumValue? Make any
> sense?
>

Modify the model may be troublesome. Anyway, I've switched to an empty
custom tag, I pass the xpath of the parent and then access the model
java style.

<customTag:parseValues source="{$root}"/>

public void doAction(TagInfo arg0, JET2Context context, JET2Writer out)
throws JET2TagException {

EList<String> allEnumValues = ((EnumVarTypeDefinition) context.getSource())
.getAllEnumValues();
for (String string : allEnumValues) {
out.write("bla bla" + string + "bla bla \n");
}
}

The problem now is that writing the output directly with out.write()
doesn't write the tabs (/t /t ...) as in the templates.

Thanks for the support :)

Nick
Re: <c:iterate> over elements [message #61099 is a reply to message #61075] Tue, 12 May 2009 13:34 Go to previous messageGo to next message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Nick Mari wrote:
>
> <customTag:parseValues source="{$root}"/>
>
> public void doAction(TagInfo arg0, JET2Context context, JET2Writer out)
> throws JET2TagException {
>
> EList<String> allEnumValues = ((EnumVarTypeDefinition) context.getSource())
> .getAllEnumValues();
> for (String string : allEnumValues) {
> out.write("bla bla" + string + "bla bla \n");
> }
> }
>
> The problem now is that writing the output directly with out.write()
> doesn't write the tabs (/t /t ...) as in the templates.
>

How about changing your parseValues tag into an iteratingTag? You'd have
to write two methods: doInitializeLoop(), which would calculate the
EList<String> and create an Iterator from it; and, doEvalLoopCondition,
which would check the iterator, advance it if necessary, and set some
variable to the current loop...

<customTag:parseValues source="$root" var="value">
<c:get select="$value"/>
</customTag:parseValues>


I'd also evaluate the source attribute as an XPath expression...

XPathContextExtender xpc = XPathContextExtender.getInstance(context);
Object result = xpc.resolveAsSingle(getAttribute("source"));
if(!result instanceof EnumVarTypeDefinition) {
throw new JET2TagException("source doesn't resolve to a
EnumVarTypeDefinition");
}
EList<String> allEnumValues =
((EnumVarTypeDefinition)result).getAllEnumValues();
.....


IMPORTANT - check my function names/signatures - I haven't run this
through a compiler, and, as we already know, my in-brain compiler is
unreliable :-)

> Thanks for the support :)
>
> Nick
>
Re: <c:iterate> over elements [message #61196 is a reply to message #61099] Wed, 13 May 2009 10:59 Go to previous messageGo to next message
Eclipse UserFriend
Originally posted by: nickmari77.yahoo.com

Paul Elder wrote:

> Nick Mari wrote:
>>
>> <customTag:parseValues source="{$root}"/>
>>
>> public void doAction(TagInfo arg0, JET2Context context, JET2Writer out)
>> throws JET2TagException {
>>
>> EList<String> allEnumValues = ((EnumVarTypeDefinition) context.getSource())
>> .getAllEnumValues();
>> for (String string : allEnumValues) {
>> out.write("bla bla" + string + "bla bla \n");
>> }
>> }
>>
>> The problem now is that writing the output directly with out.write()
>> doesn't write the tabs (/t /t ...) as in the templates.
>>
>
> How about changing your parseValues tag into an iteratingTag? You'd have
> to write two methods: doInitializeLoop(), which would calculate the
> EList<String> and create an Iterator from it; and, doEvalLoopCondition,
> which would check the iterator, advance it if necessary, and set some
> variable to the current loop...
>
> <customTag:parseValues source="$root" var="value">
> <c:get select="$value"/>
> </customTag:parseValues>
>

I thought about using an iterating tag, but I didn't understand how
to write back without using out.write()... Now I've understood and it
works better. And no more spacing problems ;) Thanks!

>
> I'd also evaluate the source attribute as an XPath expression...
>
> XPathContextExtender xpc = XPathContextExtender.getInstance(context);
> Object result = xpc.resolveAsSingle(getAttribute("source"));
> if(!result instanceof EnumVarTypeDefinition) {
> throw new JET2TagException("source doesn't resolve to a
> EnumVarTypeDefinition");
> }
> EList<String> allEnumValues =
> ((EnumVarTypeDefinition)result).getAllEnumValues();
> ....
>
>
> IMPORTANT - check my function names/signatures - I haven't run this
> through a compiler, and, as we already know, my in-brain compiler is
> unreliable :-)

Your in-brain compiler missed that resolveAsSingle() doesn't exist :P
I think you mean resolveSingle():

XPathContextExtender xpc = XPathContextExtender.getInstance(context);
Object currentXPathContextObject = xpc.currentXPathContextObject();
String attribute = getAttribute("source");
Object result =xpc.resolveSingle(currentXPathContextObject,attribute);

But it doesn't work; problem is that getAttribute("source") returns ""
and not "{$root}".

In plugin.xml the attribute is set as

<attribute
name="source"
type="xpath"
use="required">
</attribute>

The other attribute, var, retruns the correct value using
getAttribute("var")

<attribute
name="var"
type="xpath"
use="required">
</attribute>

And what is the advantage to evaluate the source attribute as xpath
expression?

Thanks!

Nick
Re: <c:iterate> over elements [message #61269 is a reply to message #61196] Fri, 15 May 2009 13:14 Go to previous message
Paul Elder is currently offline Paul ElderFriend
Messages: 849
Registered: July 2009
Senior Member
Nick Mari wrote:
> Paul Elder wrote:
snip
> Your in-brain compiler missed that resolveAsSingle() doesn't exist :P
> I think you mean resolveSingle():
>
> XPathContextExtender xpc = XPathContextExtender.getInstance(context);
> Object currentXPathContextObject = xpc.currentXPathContextObject();
> String attribute = getAttribute("source");
> Object result =xpc.resolveSingle(currentXPathContextObject,attribute);
>
> But it doesn't work; problem is that getAttribute("source") returns ""
> and not "{$root}".
>

JET treats an XPath expression within {} as a 'dynamic expression'. It
is evaluated before the tag handler sees the result of getAttribute().
IN your case, $root probably refers to the root element of your model.
When converting this to a string, the XPath engine traverses the entire
document, looking for 'text' elements, and concatenates them all together.

You want to set the source attributes as:

<your:tag
source="$root" />





> In plugin.xml the attribute is set as
>
> <attribute
> name="source"
> type="xpath"
> use="required">
> </attribute>
>

This is correct. The type="xpath" attribute has no impact on the runtime
environment. It is provided as a hint to editors that might choose to
provide code assist.

> The other attribute, var, retruns the correct value using
> getAttribute("var")
>
> <attribute
> name="var"
> type="xpath"
> use="required">
> </attribute>
>

A var attribute is, by convention, a name of an XPath variable. I would
set type="string" rather than type="xpath". But, this won't make any
difference to the execution of the tag.

> And what is the advantage to evaluate the source attribute as xpath
> expression?

As stated above, none - its just a hint to any editor that might want to
provide code assist.

>
> Thanks!
>
> Nick
>
Previous Topic:c:include troubles
Next Topic:organize imports beautifier?
Goto Forum:
  


Current Time: Sat Apr 20 03:15:12 GMT 2024

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

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

Back to the top