Home » Modeling » M2T (model-to-text transformation) » Possible XPath/transformation bug when dealing with optional attributes
Possible XPath/transformation bug when dealing with optional attributes [message #53041] |
Thu, 13 November 2008 08:20  |
Eclipse User |
|
|
|
I have a transformation that looks like this:
<c:iterate select="/XMI/Unique" var="uniqueApplication">
<c:log>Processing application of unique stereotype <c:get
select="$uniqueApplication/@id"/></c:log>
<c:setVariable select="$uniqueApplication/@UniquenessProperty"
var="uniqueProperty"/>
<c:if test="count($uniqueProperty) > 0">
<%-- now do something interesting --%>
</c:if>
</c:iterate>
The attribute @UniquenessProperty is optional, and in my tests I have
one case where the attribute is set, and one case where it is not. The
strange thing that happens is that if I run my transformation once, I
get the correct results (the c:if executes only for the case where the
attribute is set). If I execute the transformation again, the c:if also
executes for the case where the attribute is not set. This behavior
reliable alternates between correct and wrong as often as I care to try.
From the log output I can see that the relevant elements in the model
are always processed in the same order, that is, the element where the
attribute is set is processed before the element without the attribute.
This at least seems to exclude the possibility that a global variable
carries around values when it shouldn't.
I'm not sure but this seems to be a bug somewhere in the Xpath or
transformation engine?!
Jochen
|
|
| |
Re: Possible XPath/transformation bug when dealing with optional attributes [message #53122 is a reply to message #53095] |
Tue, 18 November 2008 09:14   |
Eclipse User |
|
|
|
Thanks, but that does not solve the problem of changing results of the
same transformation. Additionally, this test always fails when the
property is set! This does either not work on attributes, or something
with my setup is really screwed. Plus, that test statement has exactly
the same behavior as the one I'm using in my code, in the case where the
attribute is not present.
I've extended the JET template a little with debug messages:
<c:if test="count($uniqueProperty) > 0">
<c:log>Uniqueness Property set to <c:get select="$uniqueProperty"/></c:log>
pointcut setUniqueProperty( <c:get select="$className" /> _consumer ):
target(_consumer) && call( * <c:get select="$className" />+.set<c:get
select="$uniqueProperty"/>(..) );
before( <c:get select="$className" /> _consumer ): setUniqueProperty(
_consumer ) {
if ( lumi_uniquePropertySet ) {
uniqueProperty = _consumer.get<c:get select="$uniqueProperty"/>();
}
}
</c:if>
Now, what's really crazy is that the <c:get/> in the c:log produces an
error message, saying the XPath expression returned no result. But in
the other places where I use the same <c:get> it works and returns a value.
I'm starting to go crazy about this :S
Jochen
Joaquín Cañadas wrote:
> I solved a similar problem using the cardinality xpath function. You can
> try something like this:
>
> <c:choose select="$uniqueApplication/@UniquenessProperty">
> <c:when test="cardinality($uniqueApplication/UniquenessProperty, '1')
> = true">
> <%-- now do something interesting --%>
> </c:when>
> </c:choose>
>
>
> Jochen escribió:
>> I have a transformation that looks like this:
>>
>> <c:iterate select="/XMI/Unique" var="uniqueApplication">
>> <c:log>Processing application of unique stereotype <c:get
>> select="$uniqueApplication/@id"/></c:log>
>>
>> <c:setVariable select="$uniqueApplication/@UniquenessProperty"
>> var="uniqueProperty"/>
>>
>> <c:if test="count($uniqueProperty) > 0">
>> <%-- now do something interesting --%>
>> </c:if>
>> </c:iterate>
>>
>> The attribute @UniquenessProperty is optional, and in my tests I have
>> one case where the attribute is set, and one case where it is not. The
>> strange thing that happens is that if I run my transformation once, I
>> get the correct results (the c:if executes only for the case where the
>> attribute is set). If I execute the transformation again, the c:if
>> also executes for the case where the attribute is not set. This
>> behavior reliable alternates between correct and wrong as often as I
>> care to try.
>>
>> From the log output I can see that the relevant elements in the model
>> are always processed in the same order, that is, the element where the
>> attribute is set is processed before the element without the attribute.
>> This at least seems to exclude the possibility that a global variable
>> carries around values when it shouldn't.
>>
>> I'm not sure but this seems to be a bug somewhere in the Xpath or
>> transformation engine?!
>>
>> Jochen
|
|
| |
Re: Possible XPath/transformation bug when dealing with optional attributes [message #53224 is a reply to message #53148] |
Thu, 20 November 2008 04:30   |
Eclipse User |
|
|
|
My input is a UML model extended with stereotypes, both created with
Eclipse UML.
I could attach the model and transformation project, but I'm not sure if
it's appropriate to post large attachments to the group.
Jochen
Paul Elder wrote:
> Jochen:
>
> I am having trouble reproducing your problem. When I try it with input like
> the following, I get the expected results, not matter how often I run it.
>
> <XMI>
> <Unique id="1"/>
> <Unique id="2" UniquenessProperty="value"/>
> <Unique id="3"/>
> </XMI>
>
> Is you input an XML document, or is it a document serialize by EMF?
>
> Also, what versions of Eclise, EMF and JET are you using? I have used
> Ganymede SR1 (Eclipse 3.4.1, EMF 2.4.1, JET 0.9.1)
>
> Paul
>
>
|
|
| | |
Re: Possible XPath/transformation bug when dealing with optional attributes [message #53332 is a reply to message #53276] |
Fri, 21 November 2008 15:32   |
Eclipse User |
|
|
|
Jochen:
Well, I spent a half my day chasing this down - convinced that there was
something subtly wrong with the XPath engine, but in the end, it's really
simple.
Line 40 of your Unique.aj.jet template has this test:
<c:if test="cardinality($uniqueProperty, '1M') = true">
But, it should be:
<c:if test="cardinality($uniqueProperty, '1M') = true()">
Note the () after true. As originally written, the test is comparing a
boolean value with the xpath expression 'true', or in expanded form
child::true. Since JET evaluates all XPath expresions relative to the
document, this is /child::true, which, unless I'm greatly mistaken, will
always match nothing. The definition of comparing a boolean() to a node set
is to call boolean() on the node set. Since /child::true will always be
empty, boolean(/child::true) will always be false().
So, your test is doing the exact opposite of what you intended.
Paul
P.S. All was not for nothing. I did find out that the stereotype() function
I posted in late Semptember had some serious errors. And, I suspect there is
a problem related to the XML DOM (modelLoader org.eclipse.jet.xml) when it
comes to resolving expressions such as /XMI/Unique/@id.
|
|
|
Re: Possible XPath/transformation bug when dealing with optional attributes [message #53349 is a reply to message #53332] |
Sat, 22 November 2008 06:05   |
Eclipse User |
|
|
|
Paul, sorry that you wasted your time like that. This may be a minor bug
in the template, but unfortunately it doesn't solve the problem.
The true problem is that following:
The "if" statements in lines 39 and 60 should be mutually exclusive, right?
Now, when I execute the transformation for the first time and the
template is called for the class DefaultUniquePropertyTest, the correct
if get's executed. When I execute the transformation for the second
time, the wrong if statement gets executed.
This behavior alternates with every execution of the transformation, and
I can't figure out why.
If you want to waste another half afternoon tracking this, the easiest
way to check if you get the same behavior in your installation, check
the generated aspect
javax.faces.webapp.aspects.DefaultUniquePropertyTest_Unique, line 29
should alternate with each execution between:
uniqueProperty = _consumer.getId();
and
uniqueProperty = _consumer.hashCode();
If this does not happen for you, then I'm in trouble ;-)
In any case, thanks a lot for the time you already spent on this.
Jochen
Paul Elder wrote:
> Jochen:
>
> Well, I spent a half my day chasing this down - convinced that there was
> something subtly wrong with the XPath engine, but in the end, it's really
> simple.
>
> Line 40 of your Unique.aj.jet template has this test:
>
> <c:if test="cardinality($uniqueProperty, '1M') = true">
>
> But, it should be:
>
> <c:if test="cardinality($uniqueProperty, '1M') = true()">
>
> Note the () after true. As originally written, the test is comparing a
> boolean value with the xpath expression 'true', or in expanded form
> child::true. Since JET evaluates all XPath expresions relative to the
> document, this is /child::true, which, unless I'm greatly mistaken, will
> always match nothing. The definition of comparing a boolean() to a node set
> is to call boolean() on the node set. Since /child::true will always be
> empty, boolean(/child::true) will always be false().
>
> So, your test is doing the exact opposite of what you intended.
>
> Paul
>
> P.S. All was not for nothing. I did find out that the stereotype() function
> I posted in late Semptember had some serious errors. And, I suspect there is
> a problem related to the XML DOM (modelLoader org.eclipse.jet.xml) when it
> comes to resolving expressions such as /XMI/Unique/@id.
>
>
|
|
|
Stop wasting your time [message #53373 is a reply to message #53349] |
Sat, 22 November 2008 17:02  |
Eclipse User |
|
|
|
Hi Paul,
we finally found the problem. It's a silly bug attributed to the fact
that all variables are global in JET. Sorry for making you waste so much
time on that.
Jochen
|
|
|
Goto Forum:
Current Time: Thu May 01 00:44:45 EDT 2025
Powered by FUDForum. Page generated in 0.09622 seconds
|