Index of /www001/src/ports/www/zope-xmlmethods/work/ZopeXMLMethods
Name Last modified Size Description
Parent Directory 24-Jan-2008 00:14 -
CHANGES.txt 29-Mar-2003 22:45 11k
CacheManager.py 29-Mar-2003 22:45 14k
CacheManager.pyc 18-Jan-2008 23:40 17k
DEPENDENCIES.txt 29-Mar-2003 22:45 1k
FourSuite11Processor.py 29-Mar-2003 22:45 16k
FourSuite11Processor..> 18-Jan-2008 23:40 14k
FourSuiteProcessor.py 30-Mar-2003 17:14 14k
FourSuiteProcessor.pyc 18-Jan-2008 23:40 13k
GeneratorRegistry.py 03-Mar-2003 02:41 1k
GeneratorRegistry.pyc 18-Jan-2008 23:40 4k
Generators.py 22-Mar-2003 23:41 4k
Generators.pyc 18-Jan-2008 23:40 8k
ICacheManager.py 29-Mar-2003 22:45 4k
ICacheManager.pyc 18-Jan-2008 23:40 4k
INSTALL.txt 29-Mar-2003 22:45 1k
IXSLTMethod.py 29-Mar-2003 22:45 2k
IXSLTMethod.pyc 18-Jan-2008 23:40 4k
IXSLTProcessor.py 29-Mar-2003 22:45 3k
IXSLTProcessor.pyc 18-Jan-2008 23:40 4k
LICENSE.txt 23-Mar-2003 20:37 2k
LibXsltProcessor.py 29-Mar-2003 22:45 9k
LibXsltProcessor.pyc 18-Jan-2008 23:40 8k
ProcessorChooser.py 30-Mar-2003 15:52 6k
ProcessorChooser.pyc 18-Jan-2008 23:40 8k
PyanaProcessor.py 29-Mar-2003 22:45 14k
PyanaProcessor.pyc 18-Jan-2008 23:40 14k
SabPythProcessor.py 29-Mar-2003 22:45 13k
SabPythProcessor.pyc 18-Jan-2008 23:40 14k
TODO.txt 29-Mar-2003 22:45 8k
TUTORIAL.txt 29-Mar-2003 22:45 20k
XSLTMethod.py 29-Mar-2003 22:45 24k
XSLTMethod.pyc 18-Jan-2008 23:40 23k
__init__.py 29-Mar-2003 22:45 2k
__init__.pyc 18-Jan-2008 23:40 3k
help/ 06-Apr-2003 22:03 -
refresh.txt 23-Jul-2002 16:21 0k
tests/ 18-Jan-2008 23:40 -
version.txt 03-Mar-2003 02:41 1k
www/ 06-Apr-2003 22:03 -
################################################################
$RCSfile: README.txt,v $
Authors: Chip Morris and Craeg Strong, Ariel Partners LLC
Philipp von Weitershausen, philiKON Valley
$Date: 2003/03/30 03:45:47 $
################################################################
Contents
1. Successor project to XMLTransform
2. Quick Start
3. Prerequisites
4. Description
5. Known Limitations
6. Contributions
7. Schema Migration
8. XSLT Processor Support Status
9. Notes
10. Unit Testing on Win32
Synopsis: ZopeXMLMethods 1.0 released
ZopeXMLMethods provides methods to apply to Zope objects for XML/XSLT
processing. XSLTMethod associates XSLT transformers with XML
documents. ZopeXMLMethods succeeds XMLTransform. It features
file-system caching and works with many XML/XSLT libraries.
Successor Project to XMLTransform
ZopeXMLMethods release 1.0 represents a fundamental change in
paradigm. Rather than pointing directly to both the XML source and
the XSLT source, an XSLTMethod now points at the XSLT source and is
*applied* to the XML source like a python script or DTML method.
This is good news, as it makes XSLTMethod much more Zope-ish and
completely obviates the XML Transformer Registry. However, the down
side is that there is no easy upgrade path from previous releases.
Summary of changes
- Removed DTML GUI pages, replaced with Zope Page Templates
- Zope Page Templates now required
- XMLTransform module: renamed to ZopeXMLMethods
- XMLTransform class: enhanced and renamed to XSLTMethod
- TransformerRegistry class: removed
- FourSuite/Pyana/LibXslt/SabPythProcessor classes: upgraded to
support newer releases, but otherwise unchanged
- CacheManager class: enhanced to use the transformation path (URL)
as the caching key
Quick Start
**Don't forget to read the Prerequisites section below!**
ZopeXMLMethods consists of a set of methods that can be applied to
Zope objects to perform various types of XML processing. In general
each type of method is applied to a Zope object in the same manner
that a standard DTML Method or Python Script might be applied. The
only requirement for the source Zope object is that it must somehow
produce XML. Currently, this XML must be in ASCII form, but in the
future additional formats such as DOM or SAX events will be
supported. ZopeXMLMethods includes a Cache Manager that is
specialized to notice changes to the XML source files and to store
cached contents in files in the filesystem, rather than the Zope
object database.
ZopeXMLMethods is the successor project to XMLTransform.
Unfortunately it is not backward compatible due to the change in
usage paradigm and increased project scope. Some upgrade hints are
included in the documentation, however. The XMLTransform project is
now considered obsolete. ZopeXMLMethods is now hosted on
SourceForge. The project page is located
"here":http://zopexmlmethods.sourceforge.net
As of today, ZopeXMLMethods includes XSLTMethod, which enables Zope
users to associate an XSLT transformer with an XML document that
automatically renders the result of the transformation when called.
It is applied to another Zope object in the same manner that a DTML
Method or Python Script is applied. The XSLTMethod can behave like
a number of standard Zope objects, so that the output of a
transformation can be used in place of a normal Zope object. There
are no constraints on the type of Zope objects used for the XML or
XSLT. In fact, the content may cobbled together from multiple
sources, as long as the final content may be obtained as well-formed
XML from a single object for each. Future releases of
ZopeXMLMethods will add additional methods to support additional XML
standards such as XPath, XPointer, XMLSchema, RDF, XQuery, XUpdate
etc.
ZopeXMLMethods features a pluggable architecture that makes it
possible to dynamically choose between different XML/XSLT processors
at runtime. It currently works with any of the following: 4suite
(0.11.1 and current), Gnome libxml2/libxslt, Pyana (a Python wrapper
on top of Xalan/C), and SabPyth (a Python wrapper on top of
Sablotron). The library is designed such that it should be
relatively straightforward to support additional processors in
future. It is even possible to ZSync from one Zope instance to
another where the two Zope instances use *different* XML libraries.
This makes it much easier to test or upgrade your XML processing
library or to support heterogeneous platforms.
The ZopeXMLMethods product adds two separate objects to the "Add"
menu in the Zope Management Interface:
- XSLT Method
- XML Method Cache Manager
The quickest way to get started with ZopeXMLMethods is to read the
description below, then follow the directions in TUTORIAL.txt, then
re-read the description below :-) The tutorial includes examples of
increasing complexity that should cover most normal uses of the
product. **Don't forget to read the Prerequisites section below!**
ZopeXMLMethods features a pluggable architecture that makes it
possible to dynamically choose between different XSLT Processors at
runtime. It currently works with any of the following combinations:
- "PyXML 0.6.6":http://www.sourceforge.net/projects/pyxml and
"4Suite 0.11.1":http://www.4suite.org/. For me, on either my
Win2K machine or my Red Hat Linux 8.0 machine, that means
downloading and installing the following::
PyXML-0.6.6.tar.gz
4Suite-0.11.1.tar.gz
**DON'T FORGET TO SPECIFY THE --without-xslt --without-xpath
OPTIONS FOR PYXML**
- "PyXML 0.8.2":http://www.sourceforge.net/projects/pyxml/ and
"4Suite 1.0a":ftp://ftp.4suite.org/pub/4Suite/ For me,
on either my Win2K machine or my Red Hat Linux 8.0 machine, that
means downloading and installing the following::
PyXML-0.8.2.tar.gz
4Suite-1.0a1.tar.gz
**DON'T FORGET TO SPECIFY THE --without-xpath OPTION FOR PYXML**
Note that this release of ZopeXMLMethods is *not* compatible with
4Suite 0.12.0a3, but it should be compatible with the upcoming 1.0
beta and final releases.
- "libxml2 2.5.5":http://www.xmlsoft.org/ and "libxslt
1.0.28":http://www.xmlsoft.org/ (*Python* bindings). For me, on
my Red Hat Linux 8.0 machine, that means downloading and
installing the following::
libxml2-2.5.5-1.i386.rpm
libxml2-python-2.5.5-1.i386.rpm
libxslt-1.0.28-1.i386.rpm
libxslt-python-1.0.28-1.i386.rpm
"Here":http://www.zlatkovic.com/projects/libxml/index.html is a
site with a Win2K port of the base libraries, and you can get the
python bindings "here":http://users.skynet.be/sbi/libxml-python/
My efforts at installing libxslt on windoze have been unsuccessful
so far. *If someone has successfully set up libxslt on Win2K,
please email me the recipe and I will update this document.*
- "Pyana 0.6":http://sourceforge.net/projects/pyana/. This is a
python wrapper around the apache XML parser xercesC++, version 1.4
and XSLT processor xalanC++, version 2.1 **These should not be
confused with the Java products xalanJ and xercesJ. They are
something totally different** For me, on my Red Hat Linux 8.0
machine, that means downloading and installing the following::
Pyana-0.6.0.linux-i686-extras.tar.gz
Pyana-0.6.0.linux-i686-py2.1.tar.gz
On my Win2K machine, that means downloading and installing::
Pyana-0.6.0.win32-py2.1.exe
- "SabPyth 0.52":http://www.gingerall.com/charlie/ga/xml/x_sabpyth.xml.
This is a python wrapper around the Sablotron XSLT processor,
version 0.97. For me, on my Red Hat Linux 8.0 machine, that
means downloading and installing the following::
js-1.5rc4-2.i386.rpm
sablotron-0.97-1.i386.rpm
sablotron-devel-0.97-1.i386.rpm
Sab-pyth-0.52.linux-i686.tar.gz
Unfortunately I have not been able to get Sabloton working on Red
Hat Linux 8.0. However, I did get it working on Win2K, by
downloading and installing the following::
Sablot-Win-0.97-FullPack.zip
Sab-pyth-0.52-win32-py2.1.exe
expat_win32bin_1_95_6.exe (from expat.sourceforge.net, for libexpat.dll)
One should be able to get ZopeXMLMethods working with a Java-based
XSLT processor via XML-RPC without too much trouble. See
'ZOPE\lib\python\Products\ZopeXMLMethods\IXSLTProcessor.py' for more
details. Contributions are greatfully accepted. Support Open
Source!
Prerequisites
This product requires the presence of at least one XSLT processor.
It features a pluggable architecture that makes it possible to
dynamically choose between different XSLT Processors at runtime.
Today, the product offers support for 4Suite, Pyana, SabPyth, and
GNOME libxml2/libxslt out of the box, but it should be
straightforward to add support for another library, if your favorite
is not on that list. You can either do it yourself, or ask for help
on the ZopeXMLMethods developers list at
mailto:zopexmlmethods-devel@lists.sourceforge.net
Java-based XSLT processors can be supported as well (for example,
"Saxon":http://saxon.sourceforge.net or
"XalanJ":http://xml.apache.org/xalan-j) via XML-RPC, perhaps using
EIONET's "XMLRPC":http://www.zope.org/Members/EIONET/XMLRPC product.
This requires a little extra work and more maintenance, but
shouldn't be too bad. Supporting URI resolution to local Zope
resources might be difficult, however.
Below are some quick instructions for how to setup the various
alternatives. *Please be sure to read the installation instructions
for the package you are installing.*
ZopeXMLMethods should work fine for Zope releases 2.4 and above,
provided Page Templates are installed. We have done most of our
testing on release 2.5.1 and 2.6.1 under Linux.
1. Install Zope
2. Ensure that you are starting Zope with *at least two threads*
(by default Zope starts with 4 threads, unless you change it
via the -t option)
3. Install your XML/XSLT processor libraries
4. Install ZopeXMLMethods (see
'ZOPE\lib\python\Products\ZopeXMLMethods\INSTALL.txt')
5. Ensure that ZopeXMLMethods is registered to use the particular
XSLT processor you wish (if you installed more than one).
You can use the automated test suite to check the installation.
Here's what you do:
1. Download and install
"ZopeTestCase":http://www.zope.org/Members/shh/ZopeTestCase/
carefully, as per instructions. Be sure to install it into the
'lib/python/Testing' area, *not* the 'lib/python/Products' area!
We used ZopeTestCase version 0.6.2
2. From a shell or DOS window prompt, do the following, where
'ZOPE' represents the directory in which you installed Zope.
UNIX users substitute '/' for '\'::
cd ZOPE\lib\python\Products\ZopeXMLMethods\tests
ZOPE\bin\python alltests.py
3. As long as you are running a version of 4Suite, you should see
lots of messages followed by 'OK'. That means all 45 tests ran
successfully. You are in, baby!::
Ran 45 tests in 14.712s
OK
If you are running libxslt, several of the testcases will timeout,
but it should be all done within a minute or two. you should see
lots of messages followed by 'FAILED'. Seven testcases fail, but
that is expected, because the current version of libxslt does not
yet offer support for URI resolver hooks in Python. But 38 out of
45 ain't bad!::
Ran 45 tests in 253.918s
FAILED (failures=7)
If you are running Pyana on Linux, you should see lots of messages
followed by 'FAILED'. Seven testcases fail, but that is expected,
because the current version of Pyana/Linux does not yet offer
support for URI resolver hooks in Python. But 38 out of 45 ain't
bad!::
Ran 45 tests in 15.294s
FAILED (failures=7)
If you are running Sablotron on Win32, you should see lots of
messages followed by 'FAILED'. Three testcases fail, but that is
expected, because the current version of Sablotron does not yet
offer support for XML Catalogs. But 42 out of 45 ain't bad!::
Ran 45 tests in 13.259s
FAILED (failures=3)
Description
XSLTMethod
An XSLTMethod is a Zope object that links an XML document to a
desired XSLT script. The XSLTMethod automatically runs the XSLT
transformation and renders the results when accessed through DTML
or page templates or through the web. An XSLTMethod represents
a single XSLT stylesheet. By applying the XSLTMethod to an XML
source object, you apply the underlying XSLT.
However, an XSLTMethod object does not directly contain either
the XML source document nor the XSLT transformer. Instead, it
obtains the XSLT transformer from a Zope object whose ID is
recorded as a property. It is *applied* to another Zope object
that provides the XML source in the same way that a PythonScript
or DTMLMethod might be applied to a Zope object, (i.e. via
acquisition). In this way, an XSLTMethod object represents an
XSLT script that can be applied to any number of XML source
objects. Any number of XSLTMethod objects can be applied to a
single XML source object, and a single XSLTMethod can be applied
to any number of XML source objects.
This flexibility differentiates ZopeXMLMethods from other
XML/XSLT-based Zope products, in that it recognizes the fact
that there is often a many to many relationship between XML
documents and XSLT transformers.
NOTE: it is possible to hard-code the name of a default XSLT
stylesheet to use inside of an XML document using the
<?xml-stylesheet> processing instruction (as described in this
"W3C":http://www.w3.org/TR/xml-stylesheet/ recommendation) While
there are various pros and cons for using the xml-stylesheet
processing instruction in this way, as of today ZopeXMLMethods
provides *no* particular support for this approach.
The XML source to which an XSLTMethod is applied can come from
nearly anywhere, for example:
- Content retrieved from an SQL database and converted to XML format
- A DTMLDocument that is an XML file, with portions grabbed from
other objects via DTML tags.
- An XMLFile instance (XMLFile is part of the
"XMLKit":http://www.zope.org/Members/haqa/XMLKit Zope product)
- A CVSFile object that points to an external XML document in a
CVS repository (CVSFile is part of the
"CVSFile":http://www.zope.org/Members/arielpartners/CVSFile Zope
product)
- An ExternalFile object that points to an external XML document
in the file system (ExternalFile is part of the
"ExternalFile":http://www.zope.org/Members/arielpartners/ExternalFile
Zope product)
- A Page Template, a DTML Method, A File object, etc.
- A ParsedXML object (ParsedXML is part of the
"ParsedXML":http://www.zope.org/Members/karl/ParsedXML/ParsedXML
Zope product)
- A Zope File object
In this way, XSLTMethod can be used to form "pipelines," where the
output of one object becomes the input of the next. This approach
is more modular: each kind of object performs only one task, and
can be tested and/or replaced on an individual basis. Refer to
the pipeline examples in the tutorial for more details.
Obtaining the XSLT
XSLTMethod obtains the XSLT transformer via acquisition. Here are some
examples::
XSLTMethod XSLT XSLT Transformer ID property
/root/myXForm /root/myXSLT myXSLT
OK
XSLTMethod XSLT XSLT Transformer ID property
/root/a/b/c/d/e/myXForm /root/myXSLT myXSLT
OK
XSLTMethod XSLT XSLT Transformer ID property
/root/myXForm /root/a/b/c/d/myXSLT a/b/c/d/myXSLT
OK
XSLTMethod XSLT XSLT Transformer ID property
/root/myXForm /root/a/myXSLT myXSLT
NOT OK: myXForm CANNOT FIND myXSLT
Applying it to the XML source
An XSLTMethod is applied to an XML object like a DTMLMethod.
Here are some examples::
XSLTMethod XML Browser
/root/myXForm /root/myXML http://localhost:8080/root/myXml/myXForm
OK
XSLTMethod XML Browser
/root/myXForm /root/a/b/c/myXML http://localhost:8080/root/a/b/c/myXml/myXForm
OK
XSLTMethod XML Browser
/root/a/b/c/myXForm /root/myXML http://localhost:8080/root/myXml/a/b/c/myXForm
OK
As you can see, acquisition is incredibly powerful. Use it
wisely :)
Rendering The Output: behave_like
An XSLTMethod can behave_like any number of standard Zope
objects, including:
- DTMLDocument
- PageTemplate
- DTMLMethod
- File
- ParsedXML
For example, if an XML source file was transformed via XSLT to
HTML, and that HTML included some TAL attributes, that is, it was
actually a Zope Page Template, the templates would automatically
be resolved assuming the 'behave_like' was set to "PageTemplate".
Refer to the examples in the tutorial for more details.
CacheManager
XML Method Cache Manager is a Zope object that caches the results
of processing done by a set of xxxMethod objects (only XSLTMethod as
of today). A particular Cache Manager serves the set of xxxMethod
instances within its parent folder and all subfolders (its
clients).
In contrast to Zope's built-in caching objects, XML Method Cache
Manager is specialized for use with xxxMethod objects. That
is, it will notice when either an XML source object or XSLT
transformer object have changed, and invalidate the cache file
representing the results of that particular transformation. Also,
the CacheManager stores cached content in the filesystem, *not* in
the Zope object database.
By default, XSLTMethod never caches its results. However, XSLT
processing is expensive. In the real world, there is generally no
need to transform the content every time except in rare
circumstances such as when the XML content is retrieved from a
database on the fly and changes dynamically. For all but these
rare circumstances, caching can improve performance considerably.
This is what CacheManager is for.
An xxxMethod object searches for a CacheManager instance via
acquisition. That is, it looks for it in its parent folder, than
its parent's parent, on up the tree to the root folder, and stops
when it finds the first one.
A CacheManager is a purely optional thing. Removing one will
*never* break anything -- it is purely an optimization, because
XSLT transformations (or other XML processing) can be expensive.
Every xxxMethod object has a "caching behavior" property. This
controls whether caching should be done *if* a CacheManager is
present. If a Cache Manager is *not* present, caching will never
be done, regardless of the setting of the property. The property
is there to guard against those situations where caching is
*never* appropriate, such as when dynamic content is obtained from
a database as described above.
If an xxxMethod "caching" property is set to "on" *and* a
CacheManager is present, caching will be done.
Assuming the conditions above, once a CacheManager has stored the
results of a transformation on behalf of an XSLTMethod object, the
XSLTMethod will thereafter always retrieve its results from the
CacheManager rather than re-running the transformation unless one
of the following occurs:
1. The source XML document to which it is applied is modified
2. It is applied to a different source XML document.
3. The XSLT transformer is points to is modified
4. Its XSLT transformer reference is changed to point to a
different transformer altogether.
Typically, cached content is stored in the system temporary
directory, 'c:\tmp' on windows platforms and '/tmp' on UNIX
platforms. The placement of cache files is controlled by the
Cache Manager's 'cachePrefix' property.
The CacheManager includes some convenience functionality in the
Cache tab of its Zope Management Interface. A CacheManager
operates on the set of method objects that exist in its containing
folder and all subfolders: its clients. From the Cache tab, it is
possible to perform batch operations on all of its clients, such
as:
1. Turn caching on or off
2. List the filenames for all of the currently cached content
3. Remove all the files representing the currently cached content
Note that the files that contain the cached content may be
manually removed from the disk without any ill effects.
CacheManager is robust enough to notice this and simply re-cache
(replace) the missing files the next time the relevant content is
requested.
XSLT Transformers
We typically organize our XSLT transformers in a hierarchy, for
convenience. It is useful to regard each transformer as belonging
to a *family* of transformers. The family is determined by the
format of the XML file to be transformed. For example, there might
be a DocBook family that understands the popular XML DocBook
format, a "Resume" family that understands a homegrown Resume
format, and others.
For each family, there may be several individual transformers, one
for each kind of output desired. Standard examples of different
outputs include XML (to convert XML of one format into another),
browseable HTML, printable HTML, Structured Text (STX), FO
(formatting objects), VXML, WAP, etc. Coupled with a FO processor
like "FOP":xml.apache.org/fop, one could churn out many more
output types such as PDF, PCL, PS, AWT, etc.
Typically, we create a subfolder for each family, then create a
transformer for output type as an object within the subfolder.
The transformers are then arranged in an intuitive way, such as:
- resume/html
- resume/fo
- article/html
- article/fo
But you could put them all in a base folder:
- resumeToHTML
- ArticleToSTX
Or even have multiple sublevels
- Role/Print/HTML
- Role/Print/FO
- Role/Browse/STX
- Article/Print/HTML
The possibilities are endless! Our advice is to start simple and
add structure as you add more and more transformers.
There are no requirements on transformer files other than that
they be well-formed XSLT documents. They need not produce
stand-alone HTML pages (pages with <html> tags), but can produce
HTML fragments, XML fragments, or plain text output.
XSL Parameters
Parameters may be passed to the XSLT transformation of an
XSLTMethod. If parameters are needed, create a property in the
current context named *XSLparameters*. This property should be of
type "lines", that is, it should return a (Python) sequence of
strings. It may be defined on the XSLTMethod object itself or
acquired from the XSLTMethod's context. Each name on the list is
itself looked up in the current context. If its value is a scalar,
then the pair 'name=value' will be supplied to the XSL transformer
as a parameter specification. If the value is an object, then the
pair 'name=url' is returned where url is the absolute URL of the
object. For example, suppose the *XSLparameters* value is
'["properties", "color"]'. Suppose Zope object with
id='properties' exists in the context of the current XSLTMethod,
say at 'localhost:8080/test/foobar'. Suppose the XSLTMethod
itself has a property named 'color' with value 'blue'. Then the
following parameters will be "passed on the command line" to the
XSLT transformer::
properties=localhost:8080/test/foobar
color=blue
See the tutorial for some examples of how parameters might be
used.
URN namespaces and reusable content
In certain circumstances, it is desirable to "genericize" content,
such that it is independent of the particular context in which it
is currently being used. For example, some documents may include
portions of other documents. Certain documents may be created out
of reusable "boilerplate" pieces. There may be standard legal
clauses, headers/footers, or other pieces of content that are used
in multiple places. Even XSLT transformers themselves might be
created out of reusable pieces (for example, a family of XSLT
transformers with multiple output flavors might include several
reusable templates).
In circumstances such as the above, URI resolution may be used to
avoid hardcoding document references. For example, the URN
"urn:acme:legal/header_boilerplate" might refer to a header that
is included in all legal documents. URI resolvers and XML catalog
technology was invented to provide a way to map such URNs to
actual URLs. By plugging in a different map, you can reuse the
URN in many different situations.
Fortunately, the 4Suite XML libraries support both custom URI
resolution and XML Catalogs. URNs consist of two pieces, an NID
and an NSS::
NID: namespace ID
NSS: namespace specific string
For example::
URN: urn:acme:legal/header_boilerplate
NID: acme
NSS: legal/header_boilerplate
In order to do URN lookup, there must be a string variable named
*URNnamespaces* in the context in which a new XSLTMethod is
created. It may be defined on the XSLTMethod object itself or
acquired from the XSLTMethod's context. This variable defines
the different namespaces that can be used in URNs. URNs may be
used to lookup XSLT transformers or XML documents using XPath
expressions, for example in the XSLT 'document()' function, or via
'xsl:import()' or 'xsl:include()'. The namespaces themselves can
either be the names of folders in the ZODB, or string properties
that give base URIs. If the namespace is the name of a ZODB
folder, the NSS will be interpreted as a list of Zope contexts
relative to the folder.
In the example above, the URNnamespaces property would contain a
single string "acme". You would create a folder obtainable via
acquisition from the XSLTMethod called "acme" with a subfolder
called "legal." The "legal" subfolder would contain an object
with the ID "header_boilerplate."::
Root_Folder/acme/legal/header_boilerplate
See the tutorial for some examples of URN namespaces in action.
Known Limitations
There are issues relating to caching the intermediate results of
XSLT pipelines. The problem is that cached results are associated
with URLs, but every intermediate result in an XSLT pipeline gets
the same URL. That means that each intermediate result is written
to the same cache file, on top of the previous one.
This can lead to some strange results. For example, consider a ZPT
with the following content::
<div tal:replace="here/aSource/xsltOne/xsltTwo">none</div>
If the ZPT is called "myZPT" and is located in the root folder, its
URL might be::
http://localhost:8080/myZPT
This means that the cached results of running xsltOne against
aSource, and the cached results of running xsltTwo against that in
turn are both saved to the same file. Because xsltTwo results get
written last, you generally won't notice this problem.
However, suppose you now change the ZPT to read::
<div tal:replace="here/aSource/xsltOne">none</div>
Assuming there is an XML Method Cache Manager present, you will
still see the same result, as if xsltTwo were still there! That is
because the URL has not changed, nor has the source XML nor XSLT for
xsltOne. From its point of view, nothing has changed, so it can
happily serve up the content cached with its URL.
How can we solve this? I don't know yet ;-) We need to come up with
a more powerful algorithm for generating the caching key:
REQUEST['URL'] does not differentiate links in a pipeline.
Is there a workaround? Sort of. This issue really only comes up
when you are making heavy use of caching and pipelines, and are
changing content. A workaround would be to turn caching off while
changing content, clear the cache, then turn caching back on
globally.
Contributions
We hope others find this code useful. If you have extended or
improved this product, please feel free to submit your changes to
"us":mailto:zopexmldevel@lists.sourceforge.net
We have now established ZopeXMLMethods as a new project on
"SourceForge":http://www.sourceforge.net. The new project URL
"here":http://zopexmlmethods.sourceforge.net
Schema Migration
From time to time, you may find yourself with a new version of this
product, either because we have released a "new improved" version or
from some changes you may have made on your own. How do you deal
with all of the existing instances in your ZODB that were created
with the old definition? Here is our preferred technique:
1. Find the repair() method (we usually put it at the bottom of the
respective python source file)
2. Change the repair() method so that it updates the object from the
old version to the new version
3. Create a python script in the root folder that recursively calls
repair() on each of the object with a given metatype
4. Execute the python script (the easy way is via the "test" tab)
Here is our python script. We call it "repairAll" and put it in the
ZODB root folder::
objects = context.ZopeFind(context, obj_metatypes=[metaType], search_sub=1)
map(lambda x: x[1].repair(), objects)
return map(lambda x: x[0], objects)
XSLT Processor Support Status
4Suite 0.11.1
Summary::
While this release is getting a little long in the tooth, it is still
a good choice for those who are not able to get on the bleeding edge
of the latest 4Suite releases for any reason. Another advantage:
4Suite 0.11.1 is pre-installed for many Linux distributions.
Win32 and Linux::
Test Results: 42 of 45 tests pass
Test Failures: some URL/URN issues (can be patched), XML catalogs not supported
URL Resolution: supported
URN Resolution: supported
UNICODE sources: not supported
Performance: ok
Catalog Resolver: not available
4Suite 1.0a
Summary::
This processor provides the best support for ZopeXMLMethods
today. Every feature works out of the box with good performance
and error reporting capabilities.
Win32 and Linux::
Test Results: 45 of 45 tests pass
Test Failures: None
URL Resolution: supported
URN Resolution: supported
Performance: very good
Catalog Resolver: supported
libxslt 1.0.28
Summary::
The lack of URL support renders it unusable for all but the
simplest of tasks.
Win32::
I haven't yet successfully installed libxslt on Win32
Linux::
Test Results: 38 of 45 tests pass
Test Failures: URL and URN resolution not supported
URL Resolution: available in library, but does not work in XSLTMethod(?)
URN Resolution: Not yet implemented in Python bindings
Performance: excellent
Catalog Resolver: Not yet implemented in Python bindings
Pyana 0.6
Summary::
The lack of URL support renders it unusable for all but the
simplest of tasks.
Win32::
Test Results: 42 of 45 tests pass
Test Failures: relative URL resolution not supported, no XMLCatalog
URL Resolution: does not work; but support for InputSource due in 0.8
URN Resolution: available
Performance: excellent
Catalog Resolver: Not available.
Linux::
Test Results: 38 of 45 tests pass
Test Failures: URL/URN resolution not supported,
URL Resolution: not available
URN Resolution: does not work, sees urn:foo:bar/mumble as an invalid local path
Performance: excellent
Catalog Resolver: Not available
SabPyth 0.52
Summary::
A decent all around parser. The 1.0 release is taking awhile to
get here, but should be very stable when it finally does.
Win32::
Test Results: 42 of 45 tests run
Test Failures: relative URLs don't work, no support for XML catalog
URL Resolution: works only for absolute URLs
URN Resolution: works
Performance: excellent
Catalog Resolver: Not available
Linux::
I was unable to configure Sablotron for Linux.
Notes
This document is written in structured text. For a quickie intro to
structured text, look
"here":http://www.zope.org/Documentation/Articles/STX.
Unit Testing on Win32 for Zope < 2.5.1
If you don't plan to run the automated unit test suite, this
section is irrelevant.
For some reason, the automated unit tests don't run properly for me
on win32 using the FAT file system under Zopes earlier than 2.5.1.
I found the following workaround. In the file name::
[ZOPE]\lib\python\Testing\custom_zodb.py
Where ZOPE stands for the directory in which you installed Zope,
Change line number seven::
Storage = DemoStorage(base=FileStorage(dfi,read_only=1), quota=(1<<20))
to instead read::
Storage = DemoStorage(base=FileStorage(dfi, read_only=0), quota=(1<<20))
My guess is that FAT does not support the read_only attribute as
required.