XML.com: XML From the Inside Out
oreilly.comSafari Bookshelf.Conferences.

advertisement

Automating Stylesheet Creation
by Bob DuCharme | Pages: 1, 2, 3

The generating stylesheet's next template rule tells the XSLT processor not to apply any template rules to name children of custom elements, because the generating stylesheet's final template rule will grab them when it needs them.

<xsl:template match="custom/name"/> 

The last template rule is the setup one that gets triggered upon finding the root of the conversion instructions document. It creates the document element of the generated style (the wh:stylesheet element), calls any other necessary template rules in the generating stylesheet, and then does two things. First, it adds a default template rule to the generated stylesheet that will copy any nodes that don't have other template rules specified for them. If your generated stylesheet will copy most of the nodes it finds without changing them, this is a good default template rule to add to your generated stylesheet. But you may want your generated stylesheet to use a different default template rule. If so, this is a good place for it.

<xsl:template match="/">
 <wh:stylesheet version="1.0">

  <xsl:apply-templates/>

   <!-- Default template rule in generated stylesheet. -->
   <wh:template match="@*|node()">
    <wh:copy>
     <wh:apply-templates select="@*|node()"/>
     </wh:copy>
   </wh:template>

<!-- If needed, generate an included
     stylesheet for custom code. -->
<xsl:if test="conversion/custom">

     <wh:include href="custElements.xsl"/>

    <exsl:document href="custElements.xsl" indent="yes">
     <wh:stylesheet version="1.0">
      <xsl:for-each select="conversion/custom/name">
       <wh:template match="{.}">
        <xsl:comment> Add custom code here </xsl:comment>
        </wh:template>
          </xsl:for-each>
        </wh:stylesheet>
     </exsl:document>
   </xsl:if>

  </wh:stylesheet>
</xsl:template> 

The most complex job of the generating stylesheet's final template rule is the generation of template rules for elements and other source nodes that require custom handling. You're lucky if your stylesheet generation system can automatically generate 90 percent of what you need, but you still need to account for the other 10 percent.

The conversionSpecs.xml file has a custom element with only one name child to indicate a source tree node that requires this special handling: img attributes of item elements. The generating stylesheet generates a separate stylesheet named custElements.xsl, where the custom code for such nodes can be written by hand to process any nodes named in conversion/custom elements. The generating stylesheet also adds a wh:include instruction to the main generated stylesheet so that an XSLT processor that executes it uses the template rules from the custom code as well. (Once you've added your customized code to custElements.xsl, keep a copy in a separate directory, because this generating stylesheet overwrites any existing custElements.xsl stylesheets each time it's run.)

The generating stylesheet creates custElements.xsl using the exsl:document extension element, one of the EXSLT extensions to XSLT 1.0 specification that I recently described in the column titled Extending XSLT with EXSLT. (Libxslt supports exsl:document, but for Saxon, use the XSLT 2.0 xsl:result-document instruction instead.) Inside this exsl:document element is a wh:stylesheet element that does the basic setup for the custElements.xsl stylesheet being created. That wh:stylesheet element will have a wh:template element for each custom/name element found in the document. To prevent these template rules from showing up as single-tag empty elements in the custElements.xsl stylesheet, an xsl:comment element creates a stub to be replaced by the actual XSLT logic for those elements.

Running Stylesheet-Generating Stylesheets

    

Also in Transforming XML

Appreciating Libxslt

Push, Pull, Next!

Seeking Equality

The Path of Control

Using Stylesheet Schemas

If all this talk of generating/generated stylesheets is confusing, an overview and diagram of the script that runs them all should make it clearer. (In the sample documents zip file, there is a gentest.bat driver file for Windows machines and a gentest.sh one for Linux machines. Both assume that the free libxslt command-line utility xsltproc is in your path.) The driver script has two lines, not counting the line that shows you the result:

  1. generating.xsl reads conversionSpecs.xml and creates the generated.xsl and custElements.xsl stylesheets based on the information found in conversionSpecs.xml.

  2. The generated stylesheet is tested: generated.xsl gets applied to sampleDoc.xml and stores the result in sampleOut.xml. It deletes the foobarNum and weather elements, strips the tags from any email elements, and executes the other tasks originally listed in conversionSpecs.xml.

diagram showing stylesheet generation workflow

Generating Stylesheets in Your Workflow

How does all this reduce the workload in your office? In the ideal scenario, when a new content type shows up, someone who doesn't necessarily know XSLT creates a new version of conversionSpecs.xml for that content type (perhaps using a GUI tool, as I described above) and then uses generating.xsl to create the stylesheet necessary to convert the new content type to the XML that your system needs. The difficult part is determining the typical transformation tasks that your shop needs and then writing the XSL code in generating.xsl to automate these tasks. The generating.xsl stylesheet shown in this article demonstrates a few automation patterns that should give you a good head start.



1 to 2 of 2
  1. It's easier nowadays
    2006-04-26 07:52:42 EuroDerf
  2. I'm afraid it's quite the opposite
    2005-11-13 09:55:18 Pillar
1 to 2 of 2