You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by James Strachan <ja...@yahoo.co.uk> on 2002/11/13 14:13:48 UTC

Re: [jelly] XPath name() function broken in CVS ?

Hi Matthew

BTW in future could you prefix your mails to commons-dev or commons-user
with [jelly]? It just helps folks figure out which bit of the commons
project you're talking about. (We should document this fact on the Jelly
site).

From: "J. Matthew Pryor" <ma...@versata.com>
> Hi
>
> This worked fine with beta-7
>
> <x:copyOf trim="false" select="$feature/feature/*[name() !=
> 'requires']"/>
>
> But now with beta-8 CVS build (as of 10 minutes ago) I get the
> following:
>
> update-version:
>
> [ERROR] BUILD FAILED
> [ERROR] Function :name
> Total time:  2 seconds
>
> The XPath expression is OK isn't it?
>
> Did I do something incorrectly?

Your XPath expression is totally fine. Though a quick piece of XPath advice,
try to use local-name() instead as name() might include a namespace prefix.
Having a dependency on the namespace prefixes used in an XML document is
considered bad form; only the local name and the namespace URI should count
really.

The short answer to this problem is...

The reason for the failure is I broke it by accident recently when adding
some new namespace aware XPath features to Jelly - many appologies. I've
created a JellyUnit test case to demonstrate the bug

http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/jelly/src/test/org/apa
che/commons/jelly/xml/suite.jelly?rev=HEAD

and the bug is now fixed in CVS. There's a new Jelly snapshot build
containing this fix, so rebuild Maven and you should be OK.


Now here's the longer explanation of what went wrong and how its been fixed
(you can stop reading now if you like)...

I recently added support for namespaces inside XPath expressions, so that
you can use any namespace prefix in scope inside an XPath expression. e.g.

<whatever xmlns:x="jelly:xml" xmlns:my="someNamespaceURI">
..
    <x:parse var="doc">
        <my:foo>
            ...
            <my:bar/>
            ...
        </my:foo>
    </x:parse>
    ...
    <x:forEach select="$doc/my:foo/my:bar">
        ...
</whatever>

However the recent changes to support the above introduced a bug whereby the
default namespace (the namespace with no prefix defined via the xmlns="..."
XML attribute) was being passed from the Jelly document into the
NamespaceContext used to evaluate the Jaxen XPath expressions. This is a
bug. The NamespaceContext should never map an empty prefix to a namespace
URI other than "". If this does happen, the XPath functions (like name())
disappear as they are registered via the "" namespace URI.

I suspect the Jelly document you were using had xmlns="..." defined which is
why the XPath expression was failing. I've now fixed this issue by
explicitly ignoring the default namespace when constructing a Jaxen
NamespaceContext.

James
-------
http://radio.weblogs.com/0112098/

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [jelly] XML element nesting out of order

Posted by "J. Matthew Pryor" <ma...@versata.com>.
James you are awesome

Thanks again !!

------------------------------------------------------------
j. matthew pryor <ma...@versata.com>
versata, inc. <www.versata.com>
 

-----Original Message-----
From: James Strachan [mailto:james_strachan@yahoo.co.uk] 
Sent: Wednesday, November 13, 2002 11:35 AM
To: J. Matthew Pryor
Cc: 'Jakarta Commons Developers'
Subject: Re: [jelly] XML element nesting out of order

Hi Matthew

From: "J. Matthew Pryor" <ma...@versata.com>
> James,
>
> I really appreciate all your help; I am making good progress. I took
out
> my default namespace and that unblocked me for now.
>
> This time I have another issue and I am not sure if the fault is mine
or
> not
>
> Here is my goal:
>     <jj:goal name="update-version">
>       <x:parse var="feature" xml="feature.xml"/>
>       <x:element name="feature">
>         <x:forEach select="$feature/feature/@*">
>             <x:set var="thename" select="local-name()"/>
>             <x:set var="thevalue" select="string()"/>
>             <j:choose>
>                 <j:when test="${thename == 'version'}">
>                     <x:attribute name="${thename}">2.2.2</x:attribute>
>                 </j:when>
>                 <j:otherwise>
>                     <x:attribute
> name="${thename}">${thevalue}</x:attribute>
>                 </j:otherwise>
>             </j:choose>
>         </x:forEach>
>         <x:copyOf trim="false" select="$feature/feature/*[local-name()
> != 'plugin']"/>
>       </x:element>
>     </jj:goal>
>
> And here is the abbreviated result:
>
> update-version:
> <description>
>       Versata Business Logic Design Suite
>    </description><copyright>
>       Copyright (c) 2002 Versata, inc. All Rights Reserved
>    </copyright><license>
>       Empty License Agreement
>    </license>
> <url>
>    <update label="Versata Business Logic Plugin"
> url="http://lynx.versata.com/lynx/builds/nightly">
> </update>
>    </url>
> <feature id="com.versata.business.logic"
> label="com.versata.business.logic" version="2.2.2"
> provider-name="Versata, In
> c." os="win32" ws="win32" nl="en" arch="x86" primary="true"></feature>
> BUILD SUCCESSFUL
> Total time:  3 seconds
>
>
> So I succeeded in updating the version number, but for some reason,
the
> <feature/> element does not contain the other sub-elements
>
> I nested the Jelly code to copy yhe sub-elemtns inside an <x:element/>
> tag in the script, but perhaps I am misinterpreting the tags
>
> TIA for any more help you can provide.

I had a sneaky feeling you might hit this current limitation before I
got
chance to fix it :-). The code had a limitation that it didn't handle
too
well child content being output inside the <x:element>. So it couldn't
handle nested <x:element> tags with <x:attribute> tags inside.

I've fixed this issue in CVS and there's a new Jelly snapshot containing
the
fix.


There is a limitation you should be careful of. You shouldn't output any
text content before all the attributes have been defined. (This avoids
having to buffer up the entire contents of the <x:element> tag before
the
attributes are output.

So this is fine..

<x:element name="foo">
    ...
    <x:attribute name="something" value="whatever"/>
    ...
    some text...

        <x:element  name="bar" value="1234"/>
        ...

however this will generate an exception

<x:element name="foo">
    some text
    <x:attribute name="x" value="1234"/>
</x:element>

I've added a new JellyUnit test case to test both nesting of elements
with
attributes and that the above does indeed throw an exception.

James
-------
http://radio.weblogs.com/0112098/

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [jelly] XML element nesting out of order

Posted by James Strachan <ja...@yahoo.co.uk>.
Hi Matthew

From: "J. Matthew Pryor" <ma...@versata.com>
> James,
>
> I really appreciate all your help; I am making good progress. I took out
> my default namespace and that unblocked me for now.
>
> This time I have another issue and I am not sure if the fault is mine or
> not
>
> Here is my goal:
>     <jj:goal name="update-version">
>       <x:parse var="feature" xml="feature.xml"/>
>       <x:element name="feature">
>         <x:forEach select="$feature/feature/@*">
>             <x:set var="thename" select="local-name()"/>
>             <x:set var="thevalue" select="string()"/>
>             <j:choose>
>                 <j:when test="${thename == 'version'}">
>                     <x:attribute name="${thename}">2.2.2</x:attribute>
>                 </j:when>
>                 <j:otherwise>
>                     <x:attribute
> name="${thename}">${thevalue}</x:attribute>
>                 </j:otherwise>
>             </j:choose>
>         </x:forEach>
>         <x:copyOf trim="false" select="$feature/feature/*[local-name()
> != 'plugin']"/>
>       </x:element>
>     </jj:goal>
>
> And here is the abbreviated result:
>
> update-version:
> <description>
>       Versata Business Logic Design Suite
>    </description><copyright>
>       Copyright (c) 2002 Versata, inc. All Rights Reserved
>    </copyright><license>
>       Empty License Agreement
>    </license>
> <url>
>    <update label="Versata Business Logic Plugin"
> url="http://lynx.versata.com/lynx/builds/nightly">
> </update>
>    </url>
> <feature id="com.versata.business.logic"
> label="com.versata.business.logic" version="2.2.2"
> provider-name="Versata, In
> c." os="win32" ws="win32" nl="en" arch="x86" primary="true"></feature>
> BUILD SUCCESSFUL
> Total time:  3 seconds
>
>
> So I succeeded in updating the version number, but for some reason, the
> <feature/> element does not contain the other sub-elements
>
> I nested the Jelly code to copy yhe sub-elemtns inside an <x:element/>
> tag in the script, but perhaps I am misinterpreting the tags
>
> TIA for any more help you can provide.

I had a sneaky feeling you might hit this current limitation before I got
chance to fix it :-). The code had a limitation that it didn't handle too
well child content being output inside the <x:element>. So it couldn't
handle nested <x:element> tags with <x:attribute> tags inside.

I've fixed this issue in CVS and there's a new Jelly snapshot containing the
fix.


There is a limitation you should be careful of. You shouldn't output any
text content before all the attributes have been defined. (This avoids
having to buffer up the entire contents of the <x:element> tag before the
attributes are output.

So this is fine..

<x:element name="foo">
    ...
    <x:attribute name="something" value="whatever"/>
    ...
    some text...

        <x:element  name="bar" value="1234"/>
        ...

however this will generate an exception

<x:element name="foo">
    some text
    <x:attribute name="x" value="1234"/>
</x:element>

I've added a new JellyUnit test case to test both nesting of elements with
attributes and that the above does indeed throw an exception.

James
-------
http://radio.weblogs.com/0112098/

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


[jelly] XML element nesting out of order

Posted by "J. Matthew Pryor" <ma...@versata.com>.
James,

I really appreciate all your help; I am making good progress. I took out
my default namespace and that unblocked me for now.

This time I have another issue and I am not sure if the fault is mine or
not

Here is my goal:
    <jj:goal name="update-version">
      <x:parse var="feature" xml="feature.xml"/>
      <x:element name="feature">
        <x:forEach select="$feature/feature/@*">
            <x:set var="thename" select="local-name()"/>
            <x:set var="thevalue" select="string()"/>
            <j:choose>
                <j:when test="${thename == 'version'}">
                    <x:attribute name="${thename}">2.2.2</x:attribute>
                </j:when>
                <j:otherwise>
                    <x:attribute
name="${thename}">${thevalue}</x:attribute>
                </j:otherwise>
            </j:choose>
        </x:forEach>
        <x:copyOf trim="false" select="$feature/feature/*[local-name()
!= 'plugin']"/>
      </x:element>
    </jj:goal>

And here is the abbreviated result:

update-version:
<description>
      Versata Business Logic Design Suite
   </description><copyright>
      Copyright (c) 2002 Versata, inc. All Rights Reserved
   </copyright><license>
      Empty License Agreement
   </license>
<url>
   <update label="Versata Business Logic Plugin"
url="http://lynx.versata.com/lynx/builds/nightly">
</update>
   </url>
<feature id="com.versata.business.logic"
label="com.versata.business.logic" version="2.2.2"
provider-name="Versata, In
c." os="win32" ws="win32" nl="en" arch="x86" primary="true"></feature>
BUILD SUCCESSFUL
Total time:  3 seconds


So I succeeded in updating the version number, but for some reason, the
<feature/> element does not contain the other sub-elements

I nested the Jelly code to copy yhe sub-elemtns inside an <x:element/>
tag in the script, but perhaps I am misinterpreting the tags

TIA for any more help you can provide.

Matthew
------------------------------------------------------------
j. matthew pryor <ma...@versata.com>
versata, inc. <www.versata.com>
 

-----Original Message-----
From: James Strachan [mailto:james_strachan@yahoo.co.uk] 
Sent: Wednesday, November 13, 2002 5:14 AM
To: J. Matthew Pryor
Cc: 'Jakarta Commons Developers'
Subject: Re: [jelly] XPath name() function broken in CVS ?

Hi Matthew

BTW in future could you prefix your mails to commons-dev or commons-user
with [jelly]? It just helps folks figure out which bit of the commons
project you're talking about. (We should document this fact on the Jelly
site).

From: "J. Matthew Pryor" <ma...@versata.com>
> Hi
>
> This worked fine with beta-7
>
> <x:copyOf trim="false" select="$feature/feature/*[name() !=
> 'requires']"/>
>
> But now with beta-8 CVS build (as of 10 minutes ago) I get the
> following:
>
> update-version:
>
> [ERROR] BUILD FAILED
> [ERROR] Function :name
> Total time:  2 seconds
>
> The XPath expression is OK isn't it?
>
> Did I do something incorrectly?

Your XPath expression is totally fine. Though a quick piece of XPath
advice,
try to use local-name() instead as name() might include a namespace
prefix.
Having a dependency on the namespace prefixes used in an XML document is
considered bad form; only the local name and the namespace URI should
count
really.

The short answer to this problem is...

The reason for the failure is I broke it by accident recently when
adding
some new namespace aware XPath features to Jelly - many appologies. I've
created a JellyUnit test case to demonstrate the bug

http://cvs.apache.org/viewcvs/jakarta-commons-sandbox/jelly/src/test/org
/apa
che/commons/jelly/xml/suite.jelly?rev=HEAD

and the bug is now fixed in CVS. There's a new Jelly snapshot build
containing this fix, so rebuild Maven and you should be OK.


Now here's the longer explanation of what went wrong and how its been
fixed
(you can stop reading now if you like)...

I recently added support for namespaces inside XPath expressions, so
that
you can use any namespace prefix in scope inside an XPath expression.
e.g.

<whatever xmlns:x="jelly:xml" xmlns:my="someNamespaceURI">
..
    <x:parse var="doc">
        <my:foo>
            ...
            <my:bar/>
            ...
        </my:foo>
    </x:parse>
    ...
    <x:forEach select="$doc/my:foo/my:bar">
        ...
</whatever>

However the recent changes to support the above introduced a bug whereby
the
default namespace (the namespace with no prefix defined via the
xmlns="..."
XML attribute) was being passed from the Jelly document into the
NamespaceContext used to evaluate the Jaxen XPath expressions. This is a
bug. The NamespaceContext should never map an empty prefix to a
namespace
URI other than "". If this does happen, the XPath functions (like
name())
disappear as they are registered via the "" namespace URI.

I suspect the Jelly document you were using had xmlns="..." defined
which is
why the XPath expression was failing. I've now fixed this issue by
explicitly ignoring the default namespace when constructing a Jaxen
NamespaceContext.

James
-------
http://radio.weblogs.com/0112098/

__________________________________________________
Do You Yahoo!?
Everything you'll ever need on one web page
from News and Sport to Email and Music Charts
http://uk.my.yahoo.com


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>