Theory: an "XML Model" library, styled after SQLObject

4 views
Skip to first unread message

Sean Jamieson

unread,
Apr 28, 2006, 9:41:55 PM4/28/06
to turbo...@googlegroups.com
First of all, let me state that I did google and find something
"similar", called EaseXML (http://xmlobject.base-art.net/). But looking
at the example, this didn't feel very natural to me; albeit better than
most generators I've seen.

What I have in mind is a way to model your XML document in terms of
python classes, much like SQLObject does with relational tables.

Examples speak louder than words, so here is my theoretical model of an
RSS2.0 document, in python classes:

class RSS2( XMLModel ):
class XMLAttrs:
_tagname = 'rss'
version = '2.0'

class channel( XMLNode ):
title = XMLString()
description = XMLString()
link = XMLString()
lastBuildDate = XMLDate( format = "%a, %d %b %Y %H:%M:%S EST" )
generator = XMLString()
docs = XMLString()

class item( XMLNodeList ):
title = XMLString()
link = XMLString()
description = XMLString()
category = XMLList( type = XMLString() )
pubDate = XMLDate( format = "%a, %d %b %Y %H:%M:%S EST" )

To me, this is expressive, simple, and elegant. There is even a
possibility if removing a lot of those class names (I'm sure
XMLString(), could just be a str(), etc) but there are some functional
concerns that I think that having these helper classes may deal with.
Look at XMLList for example, it defines a time for each item. Having
said that, these 'value' classes, all would inherit from XMLValue; but
that is an implementation detail, this is just an example.

Here is an example of usage:

feed = new rss()
feed.channel.title = 'foo'
feed.channel.description = 'bar'
feed.channel.link = 'http://foo/bar'
feed.channel.lastBuildDate = datetime.now()
feed.channel.generator = 'XML Object'
feed.channel.docs = 'http:/foo/bar/docs'

feed.channel.item[0].title = 'foo'
feed.channel.item[0].link = 'http://foo/bar/1'
feed.channel.item[0].description = 'blah blah blah.'
feed.channel.item[0].pubDate = datetime.now()
feed.channel.item[0].category = ['foo', 'bar']

## or ##

item = feed.channel.item.new() ## or possibly: feed.channel.item()
item.title = 'foo'
item.link = 'http://foo/bar/1'
item.description = 'blah blah blah.'
item.pubDate = datetime.now()
item.category = ['foo', 'bar']


I'll probably go about trying to write this reguardless, but given some
positive feedback from the list, I may be more motivated. And I am
wondering if this would be a welcome addition to turbogears.

P.S. suggestions are *always* welcome

Sean

Sean Jamieson

unread,
Apr 28, 2006, 10:26:44 PM4/28/06
to TurboGears
Oops, I made typo:

"XMLList for example, it defines a time for each item."
should be,
"XMLList for example, it defines a type for each item."

P.S. you'll also note, XMLDate (maybe should be called XMLDateTime
here) defines a default format.

jvanasco

unread,
Apr 28, 2006, 10:36:17 PM4/28/06
to TurboGears
first, forgive for making perl references - i don't know of any python
modules like this to speak of -- but i've always liked looking at
seemingly good ideas from one language and seeing how they'd work in
another.

a- look at STAN in twisted python. personally i hate it. (also, it
doesn't do classes) but its python data structure -> xml.

b- that looks something like XML::Simple in perl

c- wouldn't it be nicer as:

feed = new rss( title='foo' )
feed.addChannel( title='bar', description='baz',...)

which would be identical to

feed = new rss( title = foo)

c1 = new rssChannel ( title='bar', description='baz'...)
feed.addChannel( c1 )

in perl there's data ical , which has something similar
http://search.cpan.org/~jesse/Data-ICal-0.07/lib/Data/ICal/Entry.pm

Sean Jamieson

unread,
Apr 28, 2006, 11:17:13 PM4/28/06
to turbo...@googlegroups.com
jvanasco wrote:

>first, forgive for making perl references - i don't know of any python
>modules like this to speak of -- but i've always liked looking at
>seemingly good ideas from one language and seeing how they'd work in
>another.
>
>a- look at STAN in twisted python. personally i hate it. (also, it
>doesn't do classes) but its python data structure -> xml.
>
>

I did glance at STAN, the example horrified me

>b- that looks something like XML::Simple in perl
>
>

I've never used perl, so no comment.

>c- wouldn't it be nicer as:
>
>feed = new rss( title='foo' )
>feed.addChannel( title='bar', description='baz',...)
>
>which would be identical to
>
>feed = new rss( title = foo)
>
>c1 = new rssChannel ( title='bar', description='baz'...)
>feed.addChannel( c1 )
>
>

This is exactly what I want to *avoid*
I've used this style many times, I've even implemented it. This is how
things have to be done in other languages *ehm*PHP*ehm*. Python provides
the option for a better, more expressive way.

>in perl there's data ical , which has something similar
>http://search.cpan.org/~jesse/Data-ICal-0.07/lib/Data/ICal/Entry.pm
>
>

Sean

jvanasco

unread,
Apr 28, 2006, 11:20:41 PM4/28/06
to TurboGears
> I did glance at STAN, the example horrified me

if you think that's horrific, i once inherited maintaining something
written entirely in stan by one of its creators.

Sylvain Hellegouarch

unread,
Apr 29, 2006, 3:20:05 AM4/29/06
to turbo...@googlegroups.com
Hi there,

> This is exactly what I want to *avoid*
> I've used this style many times, I've even implemented it. This is how
> things have to be done in other languages *ehm*PHP*ehm*. Python provides
> the option for a better, more expressive way.
>
>
>
Have you looked at Amara? I don't know if that suits you though.

- Sylvain

http://uche.ogbuji.net/tech/4suite/amara/

Carlos Ribeiro

unread,
Apr 29, 2006, 5:38:08 PM4/29/06
to turbo...@googlegroups.com
On 4/28/06, Sean Jamieson <se...@barriescene.com> wrote:
What I have in mind is a way to model your XML document in terms of
python classes, much like SQLObject does with relational tables.

A long time ago I've explored this kind of "declarative" programming. There was a project started at the time, we used to call it "metatemplate". It was a framework which could be used to write any kind of hierarchical data structure using plain Python classes. There are some notes at:

http://pythonnotes.blogspot.com/2004/10/metatemplate-generic-data-templates-in.html

and there is evena project started at Python-Hosting for it:

http://metatemplate.python-hosting.com/wiki


I'll probably go about trying to write this reguardless, but given some
positive feedback from the list, I may be more motivated. And I am
wondering if this would be a welcome addition to turbogears.

Feel free to use my code as a starting point. I'm willing to resume working, I just need someone to push me a little bit :-) so if you wanna to... drop me a note.

--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: carri...@gmail.com
mail: carri...@yahoo.com

Simon Belak

unread,
Apr 29, 2006, 5:49:03 PM4/29/06
to turbo...@googlegroups.com
Evolving something like this into a fully-fledged model provider would
be a cool SoC project.

Cheers,
Simon

Carlos Ribeiro wrote:
> On 4/28/06, *Sean Jamieson* <se...@barriescene.com

> mail: carri...@gmail.com <mailto:carri...@gmail.com>
> mail: carri...@yahoo.com <mailto:carri...@yahoo.com>
>
>
> >

Carlos Ribeiro

unread,
Apr 29, 2006, 6:16:05 PM4/29/06
to turbo...@googlegroups.com
On 4/29/06, Simon Belak <simon...@hruska.si> wrote:
Evolving something like this into a fully-fledged model provider would
be a cool SoC project.

Well, I wish you're right :-) I worked hard on the concept for some time, but that was more than one year ago. At the time I missed having more people to discuss with. Perhaps it's time to resume working on the project, the repository is still up, as is the mailing list that was created at the time. If there's enough interest we can make it work now.

p.s. this is not only a concept, because the code works. I just dont know if its generic enough to use as a "library", as it was the original intent.


--
Carlos Ribeiro
Consultoria em Projetos
blog: http://rascunhosrotos.blogspot.com
blog: http://pythonnotes.blogspot.com
mail: carri...@gmail.com
mail: carri...@yahoo.com

Adam Jones

unread,
May 1, 2006, 1:28:15 PM5/1/06
to TurboGears
I guess the problem I have with this is that normally I get XML from
someone else, I build databases myself. In that I know exactly what the
spec is for the database, and unlike XML the absence of data in a
database column does not also remove it from my schema example. That
said this would be very useful for authoring.

What I would like to see is something that can make working with
existing XML easier. I would like to be able to point some code at an
xml file and give it an xpath query in exchange for some objects
representing the result, and use the class' attributes to access/change
values from the file.

Bob Ippolito

unread,
May 1, 2006, 1:42:26 PM5/1/06
to turbo...@googlegroups.com

That's more or less what ElementTree gives you, and you already have
it if you are using TurboGears since Kid depends on it.

-bob

Sean Jamieson

unread,
May 1, 2006, 2:32:03 PM5/1/06
to turbo...@googlegroups.com
Adam Jones wrote:

Generation and publishing are my initial goal, there are many parsers of
many flavours out there.
But there seems to be few decent generic toos for creating your XML.
Having said that, I find Kid is actually quite nice for that, I use it
to make my RSS2.0 feed. But, XML doesn't need templating, its ment to be
computer readable, not human readable. Therefore it should be easily
computer creatable, not human created.

Sean

Sean Jamieson

unread,
May 9, 2006, 5:30:10 PM5/9/06
to turbo...@googlegroups.com
Well, it was a bit painfull, and I ran head first into several walls.
But here is the 0.1 alpha version of XMLModel.
if the attachment didn't work, here is a temporary link:

http://www.barriescene.com/xmlmodel.tar.gz


Try it, let me know what you think, or of any bugs (patches welcome)

I'll figure out an SVN for it later on.

Sean
P.S. I just joined www.linkedin.com feel free to invite me using this
address :-)

xmlmodel.tar.gz

Sean Jamieson

unread,
May 10, 2006, 8:35:12 AM5/10/06
to turbo...@googlegroups.com
Hmm, either nobody is interested, or everybody is to busy...
I'm going to assume the latter, for the sake of my own ego :-)

Just to recap, XMLModel allows you to expressively define an XML document,
using native python classes, you can then access the elements of the XML
through
a tree of native python objects.

In the future, I'm hoping to write a parser that can take a given model,
and fill in the data from an XML document. I don't imagine this being
too dificult, as a lot of the work is done by the model itself (it
defines what data to look for).

Here is an example of how XMLModel is used:

#!/usr/bin/env python
from xmlmodel.main import *
from xmlmodel.xmlvalues import *
from datetime import datetime


class rss( XMLModel ):
class XMLAttrs:


version = '2.0'

class channel( XMLNode ):

title = XMLValue('test')
description = XMLValue('something')
link = XMLValue('http://here')
lastBuildDate = XMLDateTime( format = "%a, %d %b %Y %H:%M:%S EST" )
generator = XMLValue()
docs = XMLValue()

class item( XMLNodeList ):
title = XMLValue()
link = XMLValue()
description = XMLValue()
category = XMLList()
pubDate = XMLDateTime( format = "%a, %d %b %Y %H:%M:%S EST" )

feed = rss()

feed.channel.title = 'Latest Headlines'
feed.channel.description = 'Most Recent Headlines'
feed.channel.generator = 'XMLModel 0.1a'
feed.channel.lastBuildDate = datetime( 2006, 5, 10, 8, 24, 30 )

# Normally we would loop this ;-)
item = feed.channel.item.new()
item.title = 'foo'
item.link = 'http://foo'
item.description = 'foo bar'
item.category.append( 'foo' )
item.category.append( 'bar' )
item.pubDate = datetime( 2005, 1, 2, 3, 4, 5 )

item = feed.channel.item.new()
item.title = 'bar'
item.link = 'http://bar'
item.description = 'bar baz'
item.category.append( 'bar' )
item.category.append( 'baz' )
item.pubDate = datetime( 2006, 2, 3, 4, 5, 6 )

print feed

# or this would be ever so slightly faster
# (it made a one second difference, when generating 2.5MB of XML, on my
laptop)

# for buf in feed.toxml(): # toxml() is a generator
# print buf

Any comments, suggestions, or bug reports are welcome.

Sean

tamagawa

unread,
May 10, 2006, 10:10:26 AM5/10/06
to turbo...@googlegroups.com
Hi, here's at least one guy who's strongly interested :) but still
new to TG :(

I'll give it a try, so Sean, please please don't lose your passion!
--
TAMAGAWA ryuji
Osaka, Japan

Simon Belak

unread,
May 10, 2006, 10:27:18 AM5/10/06
to turbo...@googlegroups.com
Would you mind writing a trac/wiki page on this?

Thanks!

Cheers,
Simon

Ben Bangert

unread,
May 10, 2006, 1:28:32 PM5/10/06
to TurboGears
That's actually exactly what XQuery is for. If you want some
programmatic power with XML manipulation and query, its really hard to
beat XQuery, especially if you're using a XML database. Consider
querying an XML database, pull bits of the response, and presenting
them, all handily done in a single XQuery loop:

for $reply in $entry//reply[state = $states]
return <dd>{ $reply/author/name/last/text() }</dd>

$entry in this case is assumed to be the XML document being operated
on.

Granted XQuery is odd, and yet another language.... but if you're heavy
into XML, and want to use XML files with XPath queries and do a little
manipulation on the output (for HTML), I don't know how you can get any
better than an expression based language that treats XML as first-class
objects.

If you want to stick with as much Python as possible, I'd be more
inclined to suggest lxml as you get full XPath 1.0 queries as well as
XSLT capabilities. Though the thing that annoys me about both
ElementTree and lxml is that they don't implement__str__ method that
dump the data as a string (which would be awesome when using ET/lxml
nodes in template languages); instead you have to call another function
on them to dump their contents. That feels pretty odd to me as I'd
expect the objects themselves to either give me the string data with
__str__ or have a function attached that can dump the data.

I should also mention, if you're building web-apps with XML data that
people are giving you, pushing the data into a RDBMS rather than
keeping it structured in a XML database isn't going to help. Why not
keep the XML as XML, and use an XML database that lets you pull your
data with XPath expressions; then just print out or update nodes as
needed?

Sean Jamieson

unread,
May 10, 2006, 2:32:58 PM5/10/06
to turbo...@googlegroups.com
Ben Bangert wrote:

>That's actually exactly what XQuery is for. If you want some
>programmatic power with XML manipulation and query, its really hard to
>beat XQuery, especially if you're using a XML database. Consider
>querying an XML database, pull bits of the response, and presenting
>them, all handily done in a single XQuery loop:
>
> for $reply in $entry//reply[state = $states]
> return <dd>{ $reply/author/name/last/text() }</dd>
>
>$entry in this case is assumed to be the XML document being operated
>on.
>
>Granted XQuery is odd, and yet another language.... but if you're heavy
>into XML, and want to use XML files with XPath queries and do a little
>manipulation on the output (for HTML), I don't know how you can get any
>better than an expression based language that treats XML as first-class
>objects.
>
>

I've never heard of XQuery, but as you said, that is yet another language.
I'm creating something for python, and hopefully for turbogears if
people want it.
I never said anything about databases, IMHO xml databases are a silly
idea, xml is not ment as a mass storage medium, and is terribly
inefficient at it.

>If you want to stick with as much Python as possible, I'd be more
>inclined to suggest lxml as you get full XPath 1.0 queries as well as
>XSLT capabilities. Though the thing that annoys me about both
>ElementTree and lxml is that they don't implement__str__ method that
>dump the data as a string (which would be awesome when using ET/lxml
>nodes in template languages); instead you have to call another function
>on them to dump their contents. That feels pretty odd to me as I'd
>expect the objects themselves to either give me the string data with
>__str__ or have a function attached that can dump the data.
>
>

I do support __str__ ;-)

>I should also mention, if you're building web-apps with XML data that
>people are giving you, pushing the data into a RDBMS rather than
>keeping it structured in a XML database isn't going to help. Why not
>keep the XML as XML, and use an XML database that lets you pull your
>data with XPath expressions; then just print out or update nodes as
>needed?
>

Again, I never said anything about pushing to a database, the focus here
is on generating XML from some other processed data (could be from a
database, or some other format).
That makes this more geared towards pulling *from* the database, to
produce the XML.

Now, I do plan on adding a parser to XMLModel, so that once you've
defined your model. You can use a 'parse()' class method to return you
an instance with all the data filled in, from a conforming XML document.

But that is in the future.

Sean

Eric Larson

unread,
May 10, 2006, 3:15:26 PM5/10/06
to turbo...@googlegroups.com
I had no idea there was a decent XQuery engine available for python. I have found that XLST and XPath are not fully supported, so this is somewhat surprising. What do you suggest for working with XML in Python? I have used 4Suite stuff and the included python XML tools. Am I missing some?

Thanks!

Eric

Ben Bangert

unread,
May 10, 2006, 5:22:35 PM5/10/06
to TurboGears
Ah, yes.... there isn't a decent XQuery engine for Python. Generally if
you're using a XML database, the XML database supports XQuery. So you
put together your XQuery, send it to the XML database, get back XML
(maybe read it to XML nodes with ElementTree or lxml), then do what you
will with it.

This is my desire at least. I plan on going with the community version
of the Mark Logic XML db (http://marklogic.com/) but there's a Berkeley
DB XML engine that I've heard is decent as well
(http://sleepycat.com/products/bdbxml.html). Both of these use XQuery
for their searching, and thus you can get your resulting XML back in a
way that requires very little if any changes before you're ready to use
it in your webapp. The Mark Logic one has super-powerful search and
indexing capabilities though which makes it more of a fit for my
projects.

Regarding XSLT and XPath, I believe lxml does give you full 100% XPath
1.0 and XSLT because it uses libxml2 and libxslt. The functionality
comes at the direct con that you have to have those two libraries on
the system to use lxml. Other than that, lxml has a mostly identical
interface with ElementTree.

Back to the original issue of a "XML Model". If you use a XML database,
the issue is gone afaik. Because you just keep the XML doc as XML in
your XML database. There's no need to define a 'model', using Berkeley
DB XML, you can of course restrict the database to holding XML docs
that meet certain XML DTD's (a DTD or Schema *is* the 'Model' for XML,
no?).

If the purpose's main intent was to have a better way to deal with XML
rather than ElementTree or DOM stuff, perhaps we should be inspired by
the Ruby answer to XML? Rather than using clunky DOM access, they made
it more 'Ruby-like' (http://www.germane-software.com/software/rexml/).
Perhaps something like that so making a Python class on top of various
XML structures isn't needed, and instead we can just use the existing
XML structures in a better way?

Cheers,
Ben

Sylvain Hellegouarch

unread,
May 10, 2006, 5:38:20 PM5/10/06
to turbo...@googlegroups.com
>
> Ah, yes.... there isn't a decent XQuery engine for Python. Generally if
> you're using a XML database, the XML database supports XQuery. So you
> put together your XQuery, send it to the XML database, get back XML
> (maybe read it to XML nodes with ElementTree or lxml), then do what you
> will with it.

A long recurring dream for me as well. The XLinq idea from Microsoft is
pretty nice as well.

>
> This is my desire at least. I plan on going with the community version
> of the Mark Logic XML db (http://marklogic.com/) but there's a Berkeley
> DB XML engine that I've heard is decent as well
> (http://sleepycat.com/products/bdbxml.html). Both of these use XQuery
> for their searching, and thus you can get your resulting XML back in a
> way that requires very little if any changes before you're ready to use
> it in your webapp. The Mark Logic one has super-powerful search and
> indexing capabilities though which makes it more of a fit for my
> projects.

eXist is another a great native XML database. SQL Server 2005 has also a
nice XML support but well it's not cheap :)

>
> If the purpose's main intent was to have a better way to deal with XML
> rather than ElementTree or DOM stuff, perhaps we should be inspired by
> the Ruby answer to XML? Rather than using clunky DOM access, they made
> it more 'Ruby-like' (http://www.germane-software.com/software/rexml/).
> Perhaps something like that so making a Python class on top of various
> XML structures isn't needed, and instead we can just use the existing
> XML structures in a better way?
>

Well I'm entirely sold on Amara which is a nice library atop 4suite. It
offers a superbe pythonic API for handling XML through Python.

http://uche.ogbuji.net/tech/4suite/amara/manual-dev

And of course it provides you what 4suite offers.

- Sylvain

tamagawa

unread,
May 10, 2006, 6:04:48 PM5/10/06
to turbo...@googlegroups.com
Sylvain Hellegouarch wrote:

> eXist is another a great native XML database. SQL Server 2005 has also a
> nice XML support but well it's not cheap :)

Yes, I once tried and eXist seems to works fine with 10,000s of XML
documents.


SQLObject - 'something-could-be-named-XMLObject'
| |
SQL - XQuery/XPath
| |
DBDriver - DBdriver(XMLRPC / REST interface?)
| |
DB Engine - XMLDB Engine
(MySQL, (eXist,
SQLite ...) Mark Logic XML db, Berkeley DB XML engine...)

I think It would be great if there's a module for TG like
'something-could-be-named-XMLObject' in the picture abobe.

As TG programmer are happy using SQLObject that hides details
of layer lower than SQL, XML TG programmer would be happy
with such module.
--
TAMAGAWA Ryuji
Osaka, Japan

paron

unread,
May 11, 2006, 7:57:20 AM5/11/06
to TurboGears
Amara is terrific -- easy to use, easy to learn.

Ron

Ben Bangert

unread,
May 11, 2006, 1:19:49 PM5/11/06
to TurboGears
Unfortunately XMLObject or something like that which would somehow
obfuscate XQuery/XPath beneath it isn't really possible. The XPath is
always going to be necessary, though having a layer in between that
could translate some XPath parts to use extensions for optimization
that are in the various XML db's would be awesome.

I think Amara is a great starting point, with some minor extensions to
query a doc going through the XMLObject interface to have XPath's
translated to use the best extensions for whichever database is being
used.

Having looked over Amara, I don't see much use for a "XML Model" like
Sean proposed, since Amara makes it so Pythonic to make, parse, and
manipulate XML nodes.

Cheers,
Ben

Sean Jamieson

unread,
May 11, 2006, 2:09:57 PM5/11/06
to turbo...@googlegroups.com
Ben Bangert wrote:

> Unfortunately XMLObject or something like that which would somehow
> obfuscate XQuery/XPath beneath it isn't really possible. The XPath is
> always going to be necessary, though having a layer in between that
> could translate some XPath parts to use extensions for optimization
> that are in the various XML db's would be awesome.

However unfortunate, it is also irrelevent, the topic of XQuery/XPath is
really a tangent, and has nothing to do which this topic

> I think Amara is a great starting point, with some minor extensions to
> query a doc going through the XMLObject interface to have XPath's
> translated to use the best extensions for whichever database is being
> used.

I've just been looking at Amara, and for parsing it seems wonderful.

>
> Having looked over Amara, I don't see much use for a "XML Model" like
> Sean proposed, since Amara makes it so Pythonic to make, parse, and
> manipulate XML nodes.

Amara still doesn't do what I'm talking about. Sure it will parse an XML
document into a python object tree. But it doesn't create XML from a
Python they way I am doing it.
To generate XML, Amara does:
doc.startElement/endElement, doc.appendElement, etc that everything else
does

what I'm doing is:
class people( XMLModel )
class person( XMLNodeList )
name = XMLValue()
age = XMLValue()
birthday = XMLDateTime( format="%a, %d %b %Y %H:%M:%S EST" )
doc = people()

for rec in db:
p = doc.person.new()
p.name = rec.get('name')
p.age = rec.get('age')
p.birthday = rec.get('birthday')

print doc

in Amara, this would look like:
|writer = MarkupWriter()
writer.startDocuement()
writer.startElement( 'people' )
for rec in db:
writer.startElement( 'person' )
writer.simpleElement( 'name', content=rec.get('name') )
|| writer.simpleElement( 'age', content=rec.get('age') )
birthday = datetime.fromtimestamp( rec.get( 'birthday' ) )
|| writer.simpleElement( 'birthday', content=birthday.strftime( "%a,
%d %b %Y %H:%M:%S EST" ) )|
writer.endElement( 'person' )
writer.endElement( 'people' )
writer.endDocument()

Now, I've writen libraries to generate XML this, and various similar
ways, in various languages.
But python allows me to do it in a totally different way, which is much
more comfortable to use, and feels more like working with the language
itself, and not some XML generating library, IMHO.

( if I removed "XML" from the class names, you'd probably not even
realize the code was creating XML )

Sean

Sean Jamieson

unread,
May 11, 2006, 7:57:24 PM5/11/06
to TurboGears
ok, Thunderbird screwed up the formatting a bit:

Matt Good

unread,
May 11, 2006, 10:23:29 PM5/11/06
to turbo...@googlegroups.com

Well, this discussion may be more relevant to the Python XML SIG:
http://www.python.org/community/sigs/current/xml-sig/

You may also want to take a look Stan, which allows you to generate
XHTML quite cleanly in Python. Just a little more magic and it's just
as easy to create arbitrary XML:

from nevow import stan, flat
import datetime

class TagFactory(object):
def __getattr__(self, name):
return stan.Tag(name)

T = TagFactory()

db = [
dict(name='person1', age=10, birthday=datetime.date(1996, 1, 1)),
dict(name='person2', age=15, birthday=datetime.date(1991, 5, 21))
]

person_doc = T.people [[
T.person [
T.name [ rec.get('name') ],
T.age [ rec.get('age') ],
T.birthday [ rec.get('birthday').strftime('%x') ]
] for rec in db
]]

print flat.flatten(person_doc)


--
Matt Good <t...@matt-good.net>

Sean Jamieson

unread,
May 12, 2006, 10:10:55 AM5/12/06
to turbo...@googlegroups.com
I've looked at STAN, and its been suggested several times in this thread.
I'm sorry, but, I do not find that to be at all clean, or intuitive. I
find the syntax weird and misleading.

Ben Bangert

unread,
May 17, 2006, 12:56:50 PM5/17/06
to TurboGears
I also don't find STAN syntax to be clean. I see you're point about
generating XML, vs parsing it which the Amara toolset definitely seems
better for. I think you missed a tool though that does make creating
XML very nice using Python operator overloading, jaxml
(http://www.librelogiciel.com/software/jaxml/action_Presentation).

The largest problem I see with the class based approach is that classes
really have little to do with this as you're not maintaining state or
using instance methods. The classes are there solely to try and get the
syntax a little prettier, which I think jaxml does a great job of doing
without arbitrary classes that are thrown away purely to make some XML.

Your example with jaxml:
import jaxml
doc = jaxml.XML_document()
doc.people()
doc.person()
doc.name("Someone")
doc.age("20")
doc.birthday("11-10-70")
doc.output()

Besides for the use of classes, the main problem I see with using them
to create XML is when you have deeply nested XML structures and having
a dozen nested class creations for even slightly larger XML documents
is going to be nightmarish.

I don't think jaxml is necessarilly the best tool out there, but it
does make it very quick and easy to throw together XML which is
apparently your goal. If it's missing something, perhaps that could be
added to it?

Cheers,
Ben

Graham_Higgins

unread,
May 17, 2006, 2:42:57 PM5/17/06
to TurboGears
Sean Jamieson wrote:
> Well, it was a bit painfull, and I ran head first into several walls.
> But here is the 0.1 alpha version of XMLModel.

Thanks for posting that, Sean. I'm heading XML-wards myself but not in
a principled fashion, I just have some old Web1.0-style mixed text and
graphic content which is already marked up in docbook XML and would be
an awkward fit for markdown/SQL.

You might gain some traction from examining Kimbro Staken's work on
"Syncato", in which he has used a Sleepycat dbxml front-ended by Python
to store microformat content, for which the flexibility of XML seems
quite well-suited. See:

http://www.xmldatabases.org/WK/blog?t=category&a=Syncato

for a series of blog posts on the subject and:

http://www.xmldatabases.org/WK/blog/1031_How_do_you_manage_documents_in_the_database%3F.item

for an interesting use of XPath in the URL itself, not something I've
seen anywhere else.

Kimbro was involved in Xindice, the Apache group's XML database:

http://xml.apache.org/xindice/

HTH.

Cheers,

Graham Higgins.

Sean Jamieson

unread,
May 17, 2006, 3:12:25 PM5/17/06
to turbo...@googlegroups.com
Thanks for the link Ben, this is another interesting way to go about it.
I have one problem with it though, it's very ambiguous. There is no
structure to the data, how do I know where a tag starts or ends? What is
contained in each?

Sean

Sean Jamieson

unread,
May 17, 2006, 3:23:17 PM5/17/06
to turbo...@googlegroups.com
Hi Graham,
after a brief glance over the links you gave me, I'm not sure exactly
what Syncato is.
But I did find his example of XPath based Dictionary-style access to an
XML document quite interesting. I'll have to do further reading later.

Sean

Graham_Higgins

unread,
May 18, 2006, 7:05:16 AM5/18/06
to TurboGears
Sorry, could have a been more explicit. It's a standalone blog server
app using XML/XSLT, mediated by dbxml+python+webkit. Posts are stored
as XML in the native xmldb and retrieved/stored via GET/PUT. Webkit
handles the serving and custom python routines handle the dispatching.
There's an introduction here:

http://www.xmldatabases.org/WK/blog/262_Introducing_Syncato.item

For the convenience of other subscribers, here's an example of the
XPath URL approach:

http://www.xmldatabases.org/WK/blog/item[starts-with(pubDate/text(),
'2003-08-14')]/title/text()

>From inspection of the code, the "WK" in the URL indicates that it is a
self-hosted instance of Syncato (i.e. not vapourware).

I'm still trying to work out the pros and cons of ORM vs XPath
approaches to native XML storage. The structural properties of the
content to be stored seem to have a big influence.

Jorge Vargas

unread,
May 25, 2006, 10:38:44 AM5/25/06
to turbo...@googlegroups.com
On 4/28/06, Sean Jamieson <se...@barriescene.com> wrote:

Sorry for bringing this old topic up, but I was just playing with ElementTree yesterday and I made a link to this
I believe your model can be implemented on top of ElementTree, to give it a more friendly interface.

class RSS2( XMLModel ):
    class XMLAttrs:
        _tagname = 'rss'

        version = '2.0'

    class channel( XMLNode ):
        title = XMLString()
        description = XMLString()
        link = XMLString()
        lastBuildDate = XMLDate( format = "%a, %d %b %Y %H:%M:%S EST" )
        generator = XMLString()
        docs = XMLString()

        class item( XMLNodeList ):
            title = XMLString()
            link = XMLString()
            description = XMLString()
            category = XMLList( type = XMLString() )
            pubDate = XMLDate( format = "%a, %d %b %Y %H:%M:%S EST" )

Based on your example
all the helper classes extend the Element
even XMLModel is an extension to the Element.

So all that needs to be done is a render function that will take your class and do some calls to SubElement

One question, how will you manage optional elements in the template?

how is that?

on the other hand I remenber looking at http://manatlan.online.fr/hypy.php it's something similar but based on indentation no classes.

Sean Jamieson

unread,
May 25, 2006, 11:46:38 AM5/25/06
to turbo...@googlegroups.com
I was thinking about integrating cElementTree in the future, but to make
a quick proof of concept, I just have my toxml() manually assembling a
string, using generators.

currently, XMLValue and it's subclasses are optional, with a 'required'
bool keyword argument to __init__, also an XMLNodeList can have 0 items
(and therefore not appear)

I could add another magic attribute parsed from XMLAttrs, like _tagname,
called _required ...
but generally if a tag has child tags, its going to be used.

I've seen hypy before, some months ago, it's yet another template language;
It is an interesting idea though.

Sean


Jorge Vargas wrote:

> On 4/28/06, *Sean Jamieson* <se...@barriescene.com

Jorge Vargas

unread,
May 25, 2006, 1:35:15 PM5/25/06
to turbo...@googlegroups.com
On 5/25/06, Sean Jamieson <se...@barriescene.com> wrote:

I was thinking about integrating cElementTree in the future,

I think that is the way to go, it gives everything you need and has been tested a lot.

but to make
a quick proof of concept, I just have my toxml() manually assembling a
string, using generators.

that's ok,  but soon you'll need a nice backend :)

you actually got workign code? if it's possible can I take a look?

currently, XMLValue and it's subclasses are optional, with a 'required'
bool keyword argument to __init__, also an XMLNodeList can have 0 items
(and therefore not appear)

I could add another magic attribute parsed from XMLAttrs, like _tagname,
called _required ...

I think there should be a general way (classes,fields) to tell the engine which fields are optional and which aren't, so the render function can detect a malform object, but this could turn into a huge validation scheme which I'm not sure if you want. Although if you ever generate some xml-based std, there should be a validation

but generally if a tag has child tags, its going to be used.

yes that's the way it should

I've seen hypy before, some months ago, it's yet another template language;
It is an interesting idea though.

I like the indentation thing which is basically what your doing here, what i don't like is the placeholder which you avoid with the class structure.

------

Sean Jamieson

unread,
May 25, 2006, 2:53:59 PM5/25/06
to turbo...@googlegroups.com
Yep, working code is on pypi: http://www.python.org/pypi/xmlmodel

Jorge Vargas wrote:

> On 5/25/06, *Sean Jamieson* <se...@barriescene.com

Jorge Vargas

unread,
May 26, 2006, 3:56:58 PM5/26/06
to turbo...@googlegroups.com
On 5/25/06, Sean Jamieson <se...@barriescene.com> wrote:

Yep, working code is on pypi: http://www.python.org/pypi/xmlmodel

nice /me goes to poke around.

some comments
------------
where does this comes from?
from meta import TrackableTrackerMeta
its failing in after easy_install

>>> import xmlmodel
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "build\bdist.win32\egg\xmlmodel\__init__.py", line 1, in ?
  File "build\bdist.win32\egg\xmlmodel\main.py", line 4, in ?
ImportError: No module named meta

and I have never heard of that module
-------------
I notice your using DictObj from
http://trac.turbogears.org/turbogears/ticket/779
I think it could be replace with Bunch, as TG did
-------------
one thing that let me wondering is where does _order comes from in XMLNode
-------------
I really love your generators for the XML very nice implementation
------------
Now this will be funny even without getting it to compile I did an elementTree layout so as Linus ones said about a kernel
If it works you should be double impress :)

I added 2 methods to XMLModel which mimic what your toXML do, but since it's objects not a string I just made the recursive call there, since I couldn't run it I'm not sure I got the correct value for v
main.py.patch

Sean Jamieson

unread,
May 26, 2006, 11:25:51 PM5/26/06
to turbo...@googlegroups.com
damn Damn DAMN.

Sorry, meta.py was missing. Fixed the archive.

Please try again and let me know...

( I have no idea how many people have downloaded this and it wasn't even
working :-( )

Jorge Vargas wrote:

> On 5/25/06, *Sean Jamieson* <se...@barriescene.com
> <mailto:se...@barriescene.com>> wrote:
>
>
> Yep, working code is on pypi: http://www.python.org/pypi/xmlmodel
>
>
> nice /me goes to poke around.
>
> some comments
> ------------
> where does this comes from?
> from meta import TrackableTrackerMeta
> its failing in after easy_install
>
> >>> import xmlmodel
> Traceback (most recent call last):
> File "<stdin>", line 1, in ?
> File "build\bdist.win32\egg\xmlmodel\__init__.py", line 1, in ?
> File "build\bdist.win32\egg\xmlmodel\main.py", line 4, in ?
> ImportError: No module named meta
>
> and I have never heard of that module
> -------------
> I notice your using DictObj from
> http://trac.turbogears.org/turbogears/ticket/779
> I think it could be replace with Bunch, as TG did

yeah, I just needed something simple here, then I ended up using
DictProperty instead, which was a neat trick I figured out in the middle
of the night.

> -------------
> one thing that let me wondering is where does _order comes from in XMLNode

_order is created by the meta class, its used to determin the order of
creation, so that the xml output is predictable.

> -------------
> I really love your generators for the XML very nice implementation

Thanks, this was also quick and simple, I'm probably going to create a
'pretty format' version :-)

> ------------
> Now this will be funny even without getting it to compile I did an
> elementTree layout so as Linus ones said about a kernel
> If it works you should be double impress :)
>
> I added 2 methods to XMLModel which mimic what your toXML do, but
> since it's objects not a string I just made the recursive call there,
> since I couldn't run it I'm not sure I got the correct value for v

Hey cool, I'll merge and test it. At first glance, I can tell you that v
can be either an XMLNode or XMLValue. I'll make that change when I patch.

BTW, I'll have an svn up eventually, I just have to work out things with
a friend; using his server.

>
> Jorge Vargas wrote:
>
> > On 5/25/06, *Sean Jamieson* <se...@barriescene.com
> <mailto:se...@barriescene.com>

Sean Jamieson

unread,
May 26, 2006, 11:33:07 PM5/26/06
to turbo...@googlegroups.com
"At first glance, I can tell you that v can be either an XMLNode or
XMLValue. I'll make that change when I patch."

Sorry, I just noticed you're handling that; it's been a long day :-)

Sean

Sean Jamieson

unread,
May 27, 2006, 12:05:54 AM5/27/06
to turbo...@googlegroups.com
Ok, so I started playing with your patch.
I made a couple changes to get it closer to working
(most of the diff makes formatting consistent, sorry)

The important changes are:
1. call _createTree through self
2. add an argument to _createTree, which is a reference to the
current node object (and Element doesnt have the XMLAttrs attribute ;-)

Line 76: self._createTree( rootNode, self )

Line 79: def _createTree( self, node, obj ):
Line 80: for attr, value in obj.XMLAttrs.iteritems():

Line 83: if isinstance( v, XMLNode ) or inspect.isclass( v ) and
issubclass( v, XMLNode ):

Line 85: elif isinstance( v, XMLValue ):

But, for some reason, it is recursing infinitely (boy was that looooong
backtrace scrolling up my screen fun)

Unfortunately the message is useless, and I don't know anything about
ElementTree to understand the details of what your code does at the moment.

Sean

Jorge Vargas wrote:

main.py.patch

Uche Ogbuji

unread,
May 27, 2006, 10:15:15 AM5/27/06
to TurboGears
Eric Larson wrote:
> I had no idea there was a decent XQuery engine available for python. I have
> found that XLST and XPath are not fully supported, so this is somewhat
> surprising. What do you suggest for working with XML in Python? I have used
> 4Suite stuff and the included python XML tools. Am I missing some?

4Suite does provide full XPath and XSLT support. It also provides
EXSLT support. How did you get the impression it didn't?

There is no XQuery implementation for Python, and I wouldn't hold my
breath for one. For my part I'm not the least interested in
implementing or even using XQuery, and I gather Daniel Veillard isn't
either.


--
Uche Ogbuji Fourthought, Inc.
http://uche.ogbuji.net http://fourthought.com
http://copia.ogbuji.net http://4Suite.org
Articles: http://uche.ogbuji.net/tech/publications/

Jorge Vargas

unread,
May 27, 2006, 10:25:06 AM5/27/06
to turbo...@googlegroups.com
On 5/26/06, Sean Jamieson <se...@barriescene.com> wrote:

damn Damn DAMN.

Sorry, meta.py was missing. Fixed the archive.

that's good I almost though my google was broken since it had no idea of that module :p

Please try again and let me know...

( I have no idea how many people have downloaded this and it wasn't even
working :-( )

well it's working now :)

Jorge Vargas wrote:

> On 5/25/06, *Sean Jamieson* <se...@barriescene.com
> <mailto:se...@barriescene.com>> wrote:
>
>
>     Yep, working code is on pypi: http://www.python.org/pypi/xmlmodel
>
>
> nice /me goes to poke around.
>
> some comments
> ------------
> where does this comes from?
> from meta import TrackableTrackerMeta
> its failing in after easy_install
>
> >>> import xmlmodel
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "build\bdist.win32\egg\xmlmodel\__init__.py", line 1, in ?
>   File "build\bdist.win32\egg\xmlmodel\main.py", line 4, in ?
> ImportError: No module named meta
>
> and I have never heard of that module
> -------------
> I notice your using DictObj from
> http://trac.turbogears.org/turbogears/ticket/779
> I think it could be replace with Bunch, as TG did

yeah, I just needed something simple here, then I ended up using
DictProperty instead, which was a neat trick I figured out in the middle
of the night.

yea I saw that too but I wasn't sure

> -------------
> one thing that let me wondering is where does _order comes from in XMLNode

_order is created by the meta class, its used to determin the order of
creation, so that the xml output is predictable.

hehehe of course. it was in the file I didn't had

> -------------
> I really love your generators for the XML very nice implementation

Thanks, this was also quick and simple, I'm probably going to create a
'pretty format' version :-)

> ------------
> Now this will be funny even without getting it to compile I did an
> elementTree layout so as Linus ones said about a kernel
> If it works you should be double impress :)
>
> I added 2 methods to XMLModel which mimic what your toXML do, but
> since it's objects not a string I just made the recursive call there,
> since I couldn't run it I'm not sure I got the correct value for v

Hey cool, I'll merge and test it. At first glance, I can tell you that v
can be either an XMLNode or XMLValue. I'll make that change when I patch.

it was a bit tricky finding that out.

BTW, I'll have an svn up eventually, I just have to work out things with
a friend; using his server.

I'm behind a proxy at work most svn works
but if you make a https it will work for everyone.

Jorge Vargas

unread,
May 27, 2006, 10:38:31 AM5/27/06
to turbo...@googlegroups.com
On 5/27/06, Sean Jamieson <se...@barriescene.com> wrote:
Ok, so I started playing with your patch.
I made a couple changes to get it closer to working
(most of the diff makes formatting consistent, sorry)

no I'm sorry I didn't notice I was at 2spaces and u where at 4.

The important changes are:
    1. call _createTree through self
    2. add an argument to _createTree, which is a reference to the
current node object (and Element doesnt have the XMLAttrs attribute ;-)

woops I had that as just one function forgot to change it in the split.

Line 76: self._createTree( rootNode, self )

Line 79: def _createTree( self, node, obj ):
Line 80:     for attr, value in obj.XMLAttrs.iteritems():

yea all that makes sence.

Line 83:         if isinstance( v, XMLNode ) or inspect.isclass( v ) and
issubclass( v, XMLNode ):

i'm not sure about that part, from my reading of __init__ i though all the inner classes where "transform" to instances

Line 85:         elif isinstance( v, XMLValue ):

yes ur right about that part but shouldn't it be both checks, if it's a XMLValue instance or a instances if a subclass if it.

But, for some reason, it is recursing infinitely (boy was that looooong
backtrace scrolling up my screen fun)

Unfortunately the message is useless, and I don't know anything about
ElementTree to understand the details of what your code does at the moment.

jejeje don't worry I'll get the new package and check it out.

Eric Larson

unread,
May 27, 2006, 4:34:07 PM5/27/06
to turbo...@googlegroups.com
On 5/27/06, Uche Ogbuji <uche....@gmail.com> wrote:

Eric Larson wrote:
> I had no idea there was a decent XQuery engine available for python. I have
> found that XLST and XPath are not fully supported, so this is somewhat
> surprising. What do you suggest for working with XML in Python? I have used
> 4Suite stuff and the included python XML tools. Am I missing some?

4Suite does provide full XPath and XSLT support.  It also provides
EXSLT support.  How did you get the impression it didn't?

I had found that xsl keys caused problems the last time I messed with it. That was a while ago, so I will give it another go.

There is no XQuery implementation for Python, and I wouldn't hold my
breath for one.  For my part I'm not the least interested in
implementing or even using XQuery, and I gather Daniel Veillard isn't
either.

I am not really interested in it either.

Eric

Uche Ogbuji

unread,
Jun 4, 2006, 11:55:17 AM6/4/06
to TurboGears
Eric Larson wrote:
> On 5/27/06, Uche Ogbuji <uche....@gmail.com> wrote:
> >
> >
> > Eric Larson wrote:
> > > I had no idea there was a decent XQuery engine available for python. I
> > have
> > > found that XLST and XPath are not fully supported, so this is somewhat
> > > surprising. What do you suggest for working with XML in Python? I have
> > used
> > > 4Suite stuff and the included python XML tools. Am I missing some?
> >
> > 4Suite does provide full XPath and XSLT support. It also provides
> > EXSLT support. How did you get the impression it didn't?
>
> I had found that xsl keys caused problems the last time I messed with it.
> That was a while ago, so I will give it another go.

We do fully support keys, and have for as long as I can remember. It's
possible you ran into a bug. We do find and fix bugs from time to time
:-)

Please do try again, and if it doesn't work for you, yell loudly. I
personally maintain the code relating to keys, and I'd be happy to fix
any problems with them.

Jorge Vargas

unread,
Jun 13, 2006, 8:08:10 PM6/13/06
to turbo...@googlegroups.com
hi Sean first of all I want to apologize for sending in something and then just leaving, I have been busy with other stuff and haven't had the time to pick it up again, by the way there is a reference to redkey (or redsomething) still left.

anyway I promise I'll soon make my patch work but I was reading Bruce Eckel blog, i'm not sure if you know him but he is a big guy in Java and recently has move to python a LOT, basically he did what your code does :) maybe you want to make a post there telling him of ur code.

http://www.artima.com/weblogs/viewpost.jsp?thread=163393

On 5/27/06, Sean Jamieson <se...@barriescene.com> wrote:

Sean Jamieson

unread,
Jun 14, 2006, 11:57:09 AM6/14/06
to turbo...@googlegroups.com
Wow, I can be blind some days, thanks for pointing that out; fixed.

py.xml and the library he made are both interesting, I'd even use them
myself, they are elegant in their own ways.

I don't really see how his code works like mine. Sure the result is the
same, but that's not really relevant ;-)

His code assembles the nodes of the document at run time, with mine it's
predefined (but you can add to it at run time). I do like how he uses
addition to assemble his documents though, it seems quite flexible. It
is something I might think about adding to my own.

"You will be assimilated. Resistance is futile."
Sean

Jorge Vargas wrote:

> hi Sean first of all I want to apologize for sending in something and
> then just leaving, I have been busy with other stuff and haven't had
> the time to pick it up again, by the way there is a reference to
> redkey (or redsomething) still left.
>
> anyway I promise I'll soon make my patch work but I was reading Bruce
> Eckel blog, i'm not sure if you know him but he is a big guy in Java
> and recently has move to python a LOT, basically he did what your code
> does :) maybe you want to make a post there telling him of ur code.
>
> http://www.artima.com/weblogs/viewpost.jsp?thread=163393
>

> On 5/27/06, *Sean Jamieson * <se...@barriescene.com

Jorge Vargas

unread,
Jun 14, 2006, 12:44:29 PM6/14/06
to turbo...@googlegroups.com
On 6/14/06, Sean Jamieson <se...@barriescene.com> wrote:

Wow, I can be blind some days, thanks for pointing that out; fixed.

will you update Cheese Shop it still had the package without the meta.py file.

py.xml and the library he made are both interesting, I'd even use them
myself, they are elegant in their own ways.

I don't really see how his code works like mine. Sure the result is the
same, but that's not really relevant ;-)

is not that they work alike is that, yours is another approach to the problem :)

His code assembles the nodes of the document at run time, with mine it's
predefined (but you can add to it at run time). I do like how he uses
addition to assemble his documents though, it seems quite flexible. It
is something I might think about adding to my own.

yes that's the thing I like the most operator overloading at it's finest :)
Reply all
Reply to author
Forward
0 new messages