Namespace problems with py:if

1 view
Skip to first unread message

dbrattli

unread,
Mar 23, 2007, 7:35:22 AM3/23/07
to Genshi
Hi,

I'm new to genshi, and have problems with using namespaces together
with py:if. Here's an example:

from genshi.template import MarkupTemplate
from genshi import *

tmpl = """<?xml version="1.0"?>
<Test xmlns:py="http://genshi.edgewall.org/">
<Size py:if="size" xmlns="test:test">size</Size>
<Item/>
</Test>"""

t = MarkupTemplate(tmpl)
s = t.generate(size=1)
print s.render()

This code produces the following output:

<Test>
<Size xmlns="test:test">size</Size>
<Item/>
</Test>

But if you set size=0 with generate, the output is now:

<Test>

<Item xmlns="test:test"/>
</Test>

Looks like a bug to me. I was expecting something like this:

<Test>

<Item/>
</Test>

Tried with both '0.3.6' and '0.4dev-r525'

-- Dag

dbrattli

unread,
Mar 24, 2007, 3:06:31 PM3/24/07
to Genshi
No responses, but I have now created http://genshi.edgewall.org/ticket/107

I wanted to port my TurboGears project to use Genshi templates instead
of Kid in order to check out how much faster things would be. But it
doesn't help being faster if it can't produce correct output ;-) I
managed to get the template working by using <py:if test="...">
elements instead of using py:if attributes, but it's probably best to
stay with Kid for a while longer with the production code.

-- Dag

Shannon -jj Behrens

unread,
Mar 26, 2007, 2:33:13 PM3/26/07
to gen...@googlegroups.com
Although I don't completely understand your problem, I wouldn't say
Genshi is not fit for production. I'm using Genshi in production.

By the way, all of my templates look like:

<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:py="http://genshi.edgewall.org/"
xmlns:xi="http://www.w3.org/2001/XInclude"
py:strip="">

Stuff here.

</html>

That way all the namespaces get setup in a predictable manner.

Happy Hacking!
-jj


--
http://jjinux.blogspot.com/

Karl Guertin

unread,
Mar 26, 2007, 2:59:33 PM3/26/07
to gen...@googlegroups.com
On 3/26/07, Shannon -jj Behrens <jji...@gmail.com> wrote:
> Although I don't completely understand your problem, I wouldn't say
> Genshi is not fit for production. I'm using Genshi in production.

If you look at his example, the xmlns attribute moves from 'size' to
'item', which is definitely a bug. I don't expect attributes to jump
onto sibling nodes regardless of what happens.

The declaration is somewhat strange. It's setting the default
namespace of <Size> to "test:test". Not sure if that was intended or
xmlns:test="test" was intended. Wouldn't be an issue in real use but
attributes jumping to siblings is not good regardless.

Shannon -jj Behrens

unread,
Mar 26, 2007, 4:00:37 PM3/26/07
to gen...@googlegroups.com

I seem to recall a bug similar to this happening before.

Best Regards,
-jj

--
http://jjinux.blogspot.com/

dbrattli

unread,
Mar 28, 2007, 2:22:36 AM3/28/07
to Genshi

Karl Guertin wrote:
> The declaration is somewhat strange. It's setting the default
> namespace of <Size> to "test:test". Not sure if that was intended or
> xmlns:test="test" was intended. Wouldn't be an issue in real use but
> attributes jumping to siblings is not good regardless.

Hi, sorry for the strange namespace declaration. I just tried to make
the smallest possible cut down example of my original template. An
extract from my orignal template looks like this:

...
<Meta>
<Type xmlns="syncml:metinf">${replace.type}</Type>
<Version xmlns="syncml:metinf">${replace.version}</Version>
<Size py:if="replace.size" xmlns="syncml:metinf">${replace.size}</
Size>
</Meta>
<Item>
<Target>
....
</Item>

In this code, xmlns="syncml:metinf" also jumps down to Item

-- Dag

dbrattli

unread,
Mar 28, 2007, 3:05:43 AM3/28/07
to Genshi
On Mar 26, 8:33 pm, "Shannon -jj Behrens" <jji...@gmail.com> wrote:
> Although I don't completely understand your problem, I wouldn't say
> Genshi is not fit for production. I'm using Genshi in production.
>
> By the way, all of my templates look like:
>
> <html xmlns="http://www.w3.org/1999/xhtml"
> xmlns:py="http://genshi.edgewall.org/"
> xmlns:xi="http://www.w3.org/2001/XInclude"
> py:strip="">
>
> Stuff here.
>
> </html>
>
> That way all the namespaces get setup in a predictable manner.
>
> Happy Hacking!
> -jj

This is interesting. I have tried to experiment a bit and found out
that the following code produces correct output:

<?xml version="1.0"?>
<Test xmlns:py="http://genshi.edgewall.org/"

xmlns:ns0="syncml:metinf">
<ns0:Size py:if="0">Size</ns0:Size>
<Item/>
</Test>"

The next example produces incorrect output. If the namespace is
declared in the Size element, then the namespace jumps to Item:

<?xml version="1.0"?>
<Test xmlns:py="http://genshi.edgewall.org/" >

<ns0:Size py:if="0" xmlns:ns0="syncml:metinf">Size</ns0:Size>
<Item/>
</Test>"

If you parse the first example into an elementtree and then prints it
with tostring it will produce the same xml as the second example, but
Genshi can only handle the first example. So this must be a bug.

-- Dag

Christopher Lenz

unread,
Apr 2, 2007, 10:50:14 AM4/2/07
to gen...@googlegroups.com
Am 28.03.2007 um 09:05 schrieb dbrattli:
> This is interesting. I have tried to experiment a bit and found out
> that the following code produces correct output:
>
> <?xml version="1.0"?>
> <Test xmlns:py="http://genshi.edgewall.org/"
> xmlns:ns0="syncml:metinf">
> <ns0:Size py:if="0">Size</ns0:Size>
> <Item/>
> </Test>"
>
> The next example produces incorrect output. If the namespace is
> declared in the Size element, then the namespace jumps to Item:
>
> <?xml version="1.0"?>
> <Test xmlns:py="http://genshi.edgewall.org/" >
> <ns0:Size py:if="0" xmlns:ns0="syncml:metinf">Size</ns0:Size>
> <Item/>
> </Test>"
>
> If you parse the first example into an elementtree and then prints it
> with tostring it will produce the same xml as the second example, but
> Genshi can only handle the first example. So this must be a bug.

Definitely. The cause of the problem is that namespace declarations
become events that are separate from the start-tag event they belong
to. So when a conditional directive such as <py:if> removes an
element, the START_NS event remains in the stream whereas the start-
tag is gone, and will make the serializer add a bogus namespace
declaration.

Thanks for filing the ticket on this. I'm not yet sure how to address
the issue. Improving the namespace story has been on my list for
quite some time now, and while there have been a number of
improvements in trunk, it's nowhere near perfect yet for heavy use of
mixed namespaces in templates.

Cheers,
Chris
--
Christopher Lenz
cmlenz at gmx.de
http://www.cmlenz.net/

Christopher Lenz

unread,
Apr 2, 2007, 11:59:28 AM4/2/07
to gen...@googlegroups.com
Am 02.04.2007 um 16:50 schrieb Christopher Lenz:
> Definitely. The cause of the problem is that namespace declarations
> become events that are separate from the start-tag event they belong
> to. So when a conditional directive such as <py:if> removes an
> element, the START_NS event remains in the stream whereas the start-
> tag is gone, and will make the serializer add a bogus namespace
> declaration.

Oops, after actually looking into the issue, it's not all that bad,
and was simple to fix. It should be fixed now on trunk. I'd love to
hear whether the fix works for you!

Thanks,

dbrattli

unread,
Apr 3, 2007, 2:45:17 AM4/3/07
to Genshi
On Apr 2, 5:59 pm, Christopher Lenz <cml...@gmx.de> wrote:
> Oops, after actually looking into the issue, it's not all that bad,
> and was simple to fix. It should be fixed now on trunk. I'd love to
> hear whether the fix works for you!
>
> Thanks,
> Chris
> --
> Christopher Lenz
> cmlenz at gmx.de
> http://www.cmlenz.net/

Works like a charm with my original template! To check that you had
done your work properly, I have also checked other contructions like
<Elem py:replace="''" xmlns="testns">, <Elem py:for="item in []"
xmlns="testns"> and <Elem py:strip="True" xmlns="testns">. As I
suspected, they all fail with the previous version, but I'm happy to
say that they are now handled correctly in trunk (531).

Thanks a lot

-- Dag

Reply all
Reply to author
Forward
0 new messages