[Zope-dev] HOWTO: Zclasses based on XML Documents

Anthony Pfrunder s341625@student.uq.edu.au
Mon, 1 Nov 1999 20:21:29 +1000 (GMT+1000)


[Posted for comment before posting on www.zope.org]
This document describes a technique for subclassing XML Documents and
adding content modifing functions which work as expected.  No patches to
XML Document are required and this technique eliminates the following
issues / errors:

	* No aq_* attributes
	* Invalid / missing _id attribute
	* Failure of URL and other aquisition-based functions
	* Double adding of nodes when using insertBefore, AppendChild

The document details the creation of a ZClass based on XML Documents but
the same comments apply to a python-level Product.

Procedure:
----------
1 - Create a Zclass subclassing from _ZClass_for_XMLDocument

2 - Add a new Python Method which modifies the XML Document content in the
new Zclass

3 - Items indicated with a [*] are items where caution is required to
avoid the problems above.

[Python Method]
Parameters: self, REQUEST
Body:
# Get the first HEAD element of the XML Document.  The index [0] ensures
that a node and
# NOT a NamedNodeList is returned
head = self.getElementsByTagName('head')[0]

# [*] Create a clone of the HEAD element.  Here, the __of__ attribute
returns
# a clone of the HEAD node with the aquisition path pointing to the
Zclass.
# The aquisition path now looks like this:
#	Zclass
#	  +--> head --> <HEAD>
#	  +--> clone --> <HEAD>
# This means that the cloned node "belongs" to the same XML Document as
the source node.
# This is required for content modification to work correctly. Do NOT add
__of__ to 
# other content creation functions within XML Document as it will cause
problems
clone = head.cloneNode(1).__of__(head.OwnerDocument())

# Create a child element within the clone: <SCRIPT src="<node
path>/javascript" 
#                                                  language="javascript">
# [*] Create an empty element called script.  This element MUST be created
# from the OwnerDocument otherwise it will have a parent_node.  This
causes problems
# because when you add it to the tree it will try to delete itself from
the parent_node.
# This will fail (giving invalid _id) because it has not been initialised
yet.
# Initialisation is performed when it is added to a tree.  Therefore,
create the 
# element, add it to the tree and THEN modify attributes and add child
nodes.
# Note, use the node returned from the appendChild function for applying
attributes etc NOT
# the one returned from the initial createElement.

tmp = clone.getOwnerDocument().createElement('script')
tmp = clone.insertBefore(tmp, clone.getFirstChild())
tmp.setAttribute('src', self.absolute_url()+'/javascript')
tmp.setAttribute('language', 'javascript')
tmp.appendChild(tmp.getOwnerDocument().createTextNode('javascript code
goes here'))

If this Python Method is applied to a node within an XHTML document the
following will result:

	<head>
		<script src="http://xxx/e123/e236/javascript"
language="javascript">
			javascript code goes here
		</script>
	</head>

where e123/e236 is the URL of an exisiting node within the XML Document.
Note that because it is CLONED the original content is not changed.

Hopefully this will be of help to some people developing XML-based
Zclasses.

Cheers,

Anthony Pfrunder