[Zope] Zope XML processing

Phillip J. Eby pje@telecommunity.com
Tue, 02 Feb 1999 19:37:41 -0500


At 02:26 PM 2/2/99 -0800, Gabe Wachob wrote:
>I also thought of this:
>
>It would be nice to be able to have XML document refer to each other (via
>external entity references) as though they existed in a filesystem with the
>same directory structure as the Zope environment. That is, if doc1.xml is
>/xml/examples/dox1.xml
>

Whoa, dude...  I know just barely more than nothing about XML.  I just
think it's sort of a cool data format for certain kinds of structured
documents.  My main interest at the moment is a ZTML-friendly API for the
DOM.  It's annoying to have to do <!--#var "attributes['TITLE'].value"-->,
for example, when what you want is to just say <!--#var TITLE--> and be
done with it...  or <!--#in ITEM_elements--> to iterate over sub-elements
named ITEM.  A quickie class to do this, which I've just got finished testing:

class DOM_Browser(Acquisition.Implicit):
	"""Wrapper for DOM objects"""

	node_elems = {
'documentElement':1,'firstChild':1,'lastChild':1,'parentNode':1,
			'previousSibling':1,'nextSibling':1,'ownerDocument':1,'childNodes':2 }

	def __init__(self,node):
		self.__node__ = node

	def __getattr__(self,attr):
		n = self.__node__
		atype=self.node_elems.get(attr,0)
		if atype==1:
			return self.__class__(getattr(n,attr))
		elif atype==2:
			return map(self.__class__,getattr(n,attr))
		else:
			try:
				return getattr(n,attr)		
			except AttributeError:
				a = n.attributes
				if a is not None and a.has_key(attr):
					return a[attr].value
				if attr[-9:]=='_elements':
					if attr=='all_elements':
						return map(self.__class__,filter(lambda q:
hasattr(q,'tagName'),n.childNodes))
					else:					
						return map(self.__class__,filter(lambda q,a=attr[:-9]:
hasattr(q,'tagName') and a==q.tagName==a,n.childNodes))
				raise AttributeError,attr

	def __getitem__(self,item):
		return self.__node__[item]

	def __str__(self):
		return self.__node__.toxml()


And now by having my XML loader return DOM_Browser(document), I can write
things like:

<!--#with newsletter.newsletter_elements-->
Headlines for Issue #<!--#var issue_num-->:

<!--#in item_elements--><!--#var title-->
<!--#/in-->
<!--#/with-->

and call it on XML that looks like:

<newsletter issue_num="1">
<item title="The world is made of green cheese!">Yeah, right.</item>
<item title="DOM_Browser rocks!">Awesome.</item>
</newsletter>

And get:

Headlines for Issue #1:

The world is made of green cheese!
DOM_Browser rocks!