Programming in almost language

This is the site where you may share your knowledge and experience to eachother..

  • Categories

  • LinkedIn

  • Tweet Me

  • My footsteps

Archive for the ‘XML’ Category

ZOPE XML Methods

Posted by Praveen Kumar on October 1, 2008

Zope XML Methods

What is it?

ZopeXMLMethods provides methods to apply to Zope objects for XML/XSLT processing. XSLTMethod associates XSLT transformers with XML documents. ZopeXMLMethods succeeds the XMLTransform plug-in. It features file-system caching and works with many XML/XSLT libraries. It is written in Python.

Major features:

  • Supports the following XML/XSLT processing libraries:

  • 4Suite 1.0a, (4Suite allows users to take advantage of standard XML technologies rapidly and to develop and integrate Web-based applications. It also puts practical technologies for knowledge management projects in the hands of developers. It is implemented in Python with C extensions. )

  • libxslt 1.0.28, (Libxml2 is the XML C parser and toolkit developed for the Gnome project (but usable outside of the Gnome platform), it is free software available under the MIT License. XML itself is a metalanguage to design markup languages, i.e. text language where semantic and structure are added to the content using extra “markup” information enclosed between angle brackets. HTML is the most well-known markup language. Though the library is written in C a variety of language bindings make it available in other environments.)

  • XSLT processing including support for URN resolvers and XML catalogs (click here or here to find out more about XML catalog technology. There is also a whole section about it in the tutorial.)

  • Works with nearly any kind of Zope object that can produce XML (e.g. File, ZopePageTemplate, ParsedXML, XMLDocument, DTMLDocument, etc.)

  • Supports XSLT pipelines, where the output from one transformer is passed to the next: aXML/xslt1/xslt2/xslt3

  • Pluggable architecture makes it possible to dynamically choose between different XSLT processors at runtime.

  • Full set of unit tests. Test suite uses Stefan Holek’s excellent ZopeTestCase enhanced testing library.

Contents

  1. Successor project to XMLTransform

  2. Quick Start

  3. Prerequisites

  4. Description

  5. Known Limitations

  6. Schema Migration

  7. XSLT Processor Support Status

  8. Notes

  9. Unit Testing on Win32

1. 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

2. 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

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

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 and 4Suite 0.11.1. 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 and 4Suite 1.0a 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 and libxslt 1.0.28 (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. 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. 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 ZOPElibpythonProductsZopeXMLMethodsIXSLTProcessor.py for more details.

Contributions are greatfully accepted. Support Open Source!
3. 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 or XalanJ) via XML-RPC, perhaps using EIONET’s 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 ZOPElibpythonProductsZopeXMLMethodsINSTALL.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 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)
4. 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 processing instruction (as described in this W3C 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 Zope product)
A CVSFile object that points to an external XML document in a CVS repository (CVSFile is part of the CVSFile Zope product)
An ExternalFile object that points to an external XML document in the file system (ExternalFile is part of the ExternalFile Zope product)
A Page Template, a DTML Method, A File object, etc.
A ParsedXML object (ParsedXML is part of the 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, 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 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.

5. 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.

6. 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)

7. 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.
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.

Contents
1.Getting Started
2.Conventions
3.Hello World
4.Adding More Methods
5.Creating a Cache Manager
6.behave_like Page Template
7.Parameterizing Transformations
8.XSLT Pipelines
9.URN Resolvers
10.XML Catalogs
1. Getting Started
Before getting started, please make sure you have read and fulfilled the Prerequisites section of the README file. Installation is covered in INSTALL.txt.
You will want to create a scratch folder in your Zope Management Interface (ZMI) where you can work. For the purposes of the example, I am assuming you have created a Zope Folder in the Root Folder called scratch :
Root_Folder/scratch
Also, make sure that the Zope objects for ZopeXMLMethods appear in the Add menu of the Zope Management Interface (ZMI). If they do not, please check your prerequisites and the error log of your Zope instance. The following two new options should appear:
XSLT Method
XML Method Cache Manager
2. Conventions
I will use the ZMI and ZOPE abbreviations throughout the tutorial to mean Zope Management Interface and the directory in which you installed your Zope server, respectively.
I will use the ZOPEXMLMETHOD abbreviation throughout the tutorial to refer to the directory containing the ZopeXMLMethod product within your Zope installation. On windows systems that will be:
ZOPE\lib\python\Products\ZopeXMLMethods
and on UNIX/Linux systems that will be:
ZOPE/lib/python/Products/ZopeXMLMethods
I will use the TESTFILES abbreviation throughout the tutorial to refer to the directory containing the testfiles for the Zopexmlmethod product within your Zope installation. On windows systems that will be:
ZOPElibpythonProductsZopeXMLMethodsteststestfiles
and on UNIX/Linux systems that will be:
ZOPE/lib/python/Products/ZopeXMLMethods/tests/testfiles
I will assume that your Zope is running on port 8080 and the name of your company is acme.com, for example:
http://www.acme.com:8080/scratch/hello

Please substitute the real values as appropriate in the examples.
3. Hello World
ADD AN XSLT
In your scratch folder, select DTML Document from the ZMI Add menu. Enter simplexsl for the ID and click the Browse button next to the File field. Browse for the file simple.xsl in TESTFILES. Click the Add button.
ADD AN XML DOCUMENT
In your scratch folder, select DTML Document from the ZMI Add menu. Enter simplexml for the ID and click the Browse button next to the File field. Browse for the file simple.xml in TESTFILES. Click the Add button.
ADD AN XSLTMETHOD
Back in your scratch folder, select XSLT Method from the ZMI Add menu. Notice that the Add form indicates that a Cache Manager is currently NOT available. That is OK. In the “XML Settings” panel, type in “simplexsl” in the “XSL Transformer ID” field. In the “Standard Zope Settings” panel, type in “simplexform” for the ID. Both title and description are optional. Click the “Add” button.
CREATE A RESULT DOCUMENT
In your scratch folder, select DTML Document from the ZMI Add menu. Enter result for the ID. Click the Add And Edit button. Replace the contents of the edit buffer with:
<dtml-var expr=”simplexml.simplexform(this(), REQUEST)”>
Now click on the “Test” tab. You should see the following:
Hello, world
Congratulations! If this works, you are in business.
Now try viewing the content in another browser window. Open a new browser window and type in the following:
http://www.acme.com:8080/scratch/simplexml/simplexform

http://www.acme.com:8080/scratch/result
They should give identical results.
4. Adding More Methods
ADD AN XML DOCUMENT
In your scratch folder, select DTML Document from the ZMI Add menu. Enter paramxml for the ID and click the Browse button next to the File field. Browse for the file param.xml’ in TESTFILES. Click the Add button.
ALTERNATE
Back in your scratch folder, select Page Template from the ZMI Add menu. Enter alternatexsl for the ID and click the Browse button next to the File field. Browse for the file alternate.xsl in TESTFILES. Click the Add button.
DTMLTEST
Back in your scratch folder, select DTML Method from the ZMI Add menu. Enter dtmltestxsl for the ID and click the Browse button next to the File field. Browse for the file dtmltest.xsl in TESTFILES. Click the Add button.
ZOPE PROPERTY
Back in your scratch folder, click on the properties tab. You are now viewing properties defined on the scratch folder. Add a new property of type string with name who and value zippy
ADD MORE XSLTMETHODS
Back in your scratch folder, select XSLT Method from the ZMI Add menu. In the “XML Settings” panel, type in “alternatexsl” in the “XSL Transformer ID” field. In the “Standard Zope Settings” panel, type in “alternatexform” for the ID. Click the “Add” button.
Back in your scratch folder, select XSLT Method from the ZMI Add menu. In the “XML Settings” panel, type in “dtmltestxsl” in the “XSL Transformer ID” field. In the “Standard Zope Settings” panel, type in “dtmltestxform” for the ID. Click the “Add” button.
TESTING
Now try viewing the content in another browser window. Open a new browser window and type in the following:
http://www.acme.com:8080/scratch/simplexml/alternatexform
You should see:
Hello, world and goodbye
Now try:
http://www.acme.com:8080/scratch/paramxml/dtmltestxform

Hello, zippy
DTML Tags
Navigate to scratch/dtmltestxsl. You should now be seeing the XSL program text in the Edit tab. Notice that the DTML tag embedded in the code:
<dtml-var who>
The dtmltestxsl transformer transformed paramxml into a document that included a DTML tag which was automatically resolved to find the “who” property we added to the scratch folder. Kewl.
5. Creating a Cache Manager
ADD A CACHE MANAGER
Back in your scratch folder, select XML Method Cache Manager from the ZMI Add menu. Enter cacherInTheRye for the ID. Click on the “Add” button. Now, back in the scratch folder, click on cacherInTheRye. You should be in the Cache tab, where there are several buttons available. Don’t click on any of them yet. First, let’s find out where the cacher is going to store his files! Click on the “Properties” tab. Notice the cachePrefix Property:
c:\tmp\ZopeXMLCache
The cachePrefix is both a directory and file prefix. The value above indicates that files will be placed in the c:\tmp directory and the beginning of every file name will start with ZopeXMLCache. Setting the prefix of all cache files the same helps a great deal in identifying them — as all UNIX administrators know, tmp directories can get quite full of stuff.
Ensure that the prefix is pointing to a valid directory, either by adding the directory or changing the property, or both.
USING THE CACHE MANAGER
Back in the Cache tab for the cacherInTheRye, try pressing the different buttons. Don’t be shy. You should find them quite intuitive. If not, now would be a good time to try the help system. Click on the Help! link in the upper right hand corner of the Cache tab.
When you navigate back to the Edit tab of one of the XSLTMethod instances, you will now notice something different. It will now “Cache Manager: Root Folder/scratch/cacherInTheRye” Informative little buggers, aren’t they?
Now try running the results of the transformations using the steps above, and go back and list the files in the cache by pressing the List Files In Cache button. If you are curious, go ahead and load the cache files into a text editor and check ’em out. You can even delete them from the disk — the cache manager is smart enough to notice that and regenerate them again next time!
6. behave_like Page Template
ADD AN XML DOCUMENT
In your scratch folder, select DTML Document from the ZMI Add menu. Enter templateparamxml for the ID and click the Browse button next to the File field. Browse for the file templateparam.xml’ in TESTFILES. Click the Add button.
TEMPLATETEST
Back in your scratch folder, make a new subfolder called “sub”. Then make a new DTML Method inside the “sub” subfolder, enter templatetestxsl for the ID and click the Browse button next to the File field. Browse for the file templatetest.xsl in TESTFILES. Click the Add button. So you now have a DTML method scratch/sub/templatetestxsl
ANOTHER XSLTMETHOD
Back in your scratch folder, select XSLT Method from the ZMI Add menu. In the “XML Settings” panel, type in “sub/templatetestxsl” in the “XSL Transformer ID” field. In the “Standard Zope Settings” panel, type in “templatetestxform” for the ID. Click the “Add” button.
TEST
Now, type the following into a browser:
http://www.acme.com:8080/scratch/templateparamxml/templatetestxform

Hello, junk
Now, wait a minute! That’s not what we wanted. Click on the Properties tab for templatetestxform and change behave_like to “Page Template” and click “Save Changes”. Now try again:
http://www.acme.com:8080/scratch/templateparamxml/templatetestxform

Hello, zippy
Much better! Check out the source code to templatetest.xsl if you are curious.
CREATE A RESULT DOCUMENT
Just for completeness, let’s create a page template to see the result. In your scratch folder, select Page Template from the ZMI add menu. enter templateresult for the ID. Click the Add And Edit button. Replace the contents of the edit buffer with:
<tal:nothing tal:replace=”here/templateparamxml/templatetestxform”/>
In this case the behave_like setting of the XSLTMethod doesn’t matter, since the result is captured inside a Zope page template anyway. Also note that the parameters this() and RESULT are not required for page templates, they way they are in DTML (in the Hello World example above). Yet another reason to abandon DTML 🙂
7. Parameterizing Transformations
PARAM XSLT
Back in your scratch folder, select DTML Document from the ZMI Add menu. Enter paramxsl for the ID and click the Browse button next to the File field. Browse for the file param.xsl in TESTFILES. Click the Add button.
PARAM XSLTMETHOD
Back in your scratch folder, select XSLT Method from the ZMI Add menu. In the “XML Settings” panel, type in “paramxsl” in the “XSL Transformer ID” field. In the “Standard Zope Settings” panel, type in “paramxform” for the ID. Click the “Add” button.
SCALAR PARAMETERS
Back in your scratch folder, click on the properties tab. You are now viewing properties defined on the scratch folder. Add a new property of type lines with name XSLparameters. Enter the value “who”. Then save changes and add “message” to the list. You have just indicated to all XSLTMethod instances located underneath the scratch folder that they should use two parameters, named “who” and “message”. The parameters are grabbed using acquisition, so they can be properties or Zope objects themselves. First, let’s use (scalar) properties.

Create another Property on the scratch folder called “message” with type “string” and value “Yow! Are we having fun yet?”

TESTING

Now, type the following into a browser:

       http://www.acme.com:8080/scratch/paramxml/paramxform

       Hello, zippy and Yow! Are we having fun yet?

PROPERTIES FILE XSLT

Back in your scratch folder, select Folder from the ZMI Add menu, and add a subfolder called prop. Navigate into the prop subfolder. Select DTML Document from the ZMI Add menu. Enter propertiesfile for the ID and click the Browse button next to the File field. Browse for the file propertiesfile.xsl in TESTFILES. Click the Add button.

ANOTHER XSLTMETHOD

Also in the prop folder, create an instance of XSLTMethod using propertiesfilexform as the ID, and propertiesfile as the XSL Transformer ID.

PROPERTIES FILE XML

Back in your scratch folder, select DTML Document from the ZMI Add menu. Enter properties for the ID and click the Browse button next to the File field. Browse for the file properties.xml in TESTFILES. Click the Add button.

CHANGE XSL PARAMETERS

Back in your scratch folder, select the Properties tab, and change the XSLparameters to only a single line that says “properties”.

Now, type the following into a browser:

       http://www.acme.com:8080/scratch/paramxml/prop/propertiesfilexform

       url is http://www.acme.com:8080/scratch/properties

NB If at first you don’t see the correct output, try disabling the cache by navigating to the cacherInTheRye and pressing the Turn Caching Off button.

Did you notice how you can apply an XSLTMethod to an XML source even if the XSLTMethod is in an unrelated folder? We are essentally applying prop/propertiesfilexform to paramxml For more details on this amazing technology, please read the acquisition chapter in the Zope Developer’s Guide

8. XSLT Pipelines

XSLT stylesheets can be combined into pipelines, where the output of one stylesheet is passed on to the next. XSLTMethod makes this a piece of cake. Let’s try an example:

ADD XSLTS

Back in your scratch folder, select DTML Method from the ZMI Add menu. Enter pipeline1xsl for the ID and click the Browse button next to the File field. Browse for the file pipeline1.xsl in TESTFILES. Click the Add button.

Back in your scratch folder, select DTML Method from the ZMI Add menu. Enter pipeline2xsl for the ID and click the Browse button next to the File field. Browse for the file pipeline2.xsl in TESTFILES. Click the Add button.

Back in your scratch folder, select DTML Method from the ZMI Add menu. Enter pipeline3xsl for the ID and click the Browse button next to the File field. Browse for the file pipeline3.xsl in TESTFILES. Click the Add button.

ADD XSLTMETHODS

Back in your scratch folder, select XSLT Method from the ZMI Add menu. Enter xslt1 for the ID and pipeline1xsl for the “XSL Transformer ID” field. Click the “Add” button.

Back in your scratch folder, select XSLT Method from the ZMI Add menu. Enter xslt2 for the ID and pipeline2xsl for the “XSL Transformer ID” field. Click the “Add” button.

Back in your scratch folder, select XSLT Method from the ZMI Add menu. Enter xslt3 for the ID and pipeline3xsl for the “XSL Transformer ID” field. Click the “Add” button.

TEST

Now, type the following into a browser:

       http://www.acme.com:8080/scratch/simplexml/xslt1/xslt2/xslt3

       Hello, world

Now just for fun, try inspecting each step in the pipeline. After each one, you may have to select View Page Source in your browser in order to see the native XML. Note that you may have to turn caching off for this to work correctly; see Known Limitations in the README file. :

       http://www.acme.com:8080/scratch/simplexml/xslt1

       http://www.acme.com:8080/scratch/simplexml/xslt1/xslt2

       http://www.acme.com:8080/scratch/simplexml/xslt1/xslt2/xslt3

9. URN Resolvers

This capability is currently only supported using 4Suite

PROPERTIES FILE XSLT

Back in your scratch folder, select DTML Document from the ZMI Add menu. Enter calldocumentfuncURN for the ID and click the Browse button next to the File field. Browse for the file calldocumentfuncURN.xsl in TESTFILES. Click the Add button.

PROPERTIES FILE XSLTMETHOD

Back in your scratch folder, select Folder from the ZMI Add menu, and add a subfolder called urntest. Navigate into the urntest subfolder. Create an XSLTMethod instance inside the urntest subfolder with ID calldocumentfuncxform and XSL Transform ID calldocumentfuncURN

CREATE PROPERTY FILE

Back in the scratch folder, create a subfolder with the ID “arielpartners”. Then create a subfolder within arielpartners called “propfolder”. Finally, create a subfolder within propfolder called “foo”. Within the foo folder, create a DTMLDocument with ID “properties” by uploading the “properties.xml” file from TESTFILES. You now have a Zope object:

           Root_Folder/scratch/arielpartners/propfolder/foo/properties

    URN NAMESPACE REGISTRATION

      Back in your scratch folder, click on the properties tab.  You
      are now viewing properties defined on the scratch folder.  Add a
      new property of type 'lines' with name 'URNnamespaces'.  Enter
      the value "arielpartners".  Then save changes.  You have just
      indicated to all XSLTMethod instances located underneath the
      scratch folder that the "arielpartners" folder is now available
      as a URN namespace.  That is, it can be used as the "NID" piece
      of a URN (see README.txt for more details).  The "NSS" portion
      of a URN will be interpreted as a Zope path relative to the NID.
      We will see how this works below.

    TEST

      Now, type the following into a browser::

        http://www.acme.com:8080/scratch/urntest/paramxml/calldocumentfuncxform

        Hello, sneezy

      URN resolution works the same way in xsl:include and xsl:import
      statements.  Have fun!

9. XML Catalog files

This capability is currently only supported using 4Suite

Use the very same setup as in the previous section. However, move the properties object from the scratch/arielpartners/propfolder/foo folder to a new scratch/bar folder. Make sure that there are no other copies of the properties object anywhere else (you may have to remove the version in the scratch folder from the Parameterizing Transformations lesson).

XML CATALOG FILE

Back in your scratch folder, select DTML Document from the ZMI Add menu. Enter catalog for the ID and click the Browse button next to the File field. Browse for the file catalog.xml in TESTFILES. Click the Add button.

XML CATALOG REGISTRATION

Back in your scratch folder, click on the properties tab. You are now viewing properties defined on the scratch folder. Add a new property of type string with name XMLcatalog. Enter the value “catalog”. Then save changes. You have just indicated to all XSLTMethod instances located underneath the scratch folder that the “catalog” object contains an XML Catalog to be used for URI resolution. You can do many complex and wonderful things with catalogs. For more details, please see README.txt

TEST

Now, type the following into a browser:

        http://www.acme.com:8080/scratch/urntest/paramxml/calldocumentfuncxform

        Hello, sneezy

Posted in XML | 3 Comments »