[Home]  [List]  [News]  [Docs]  [FAQ]  [Downloads]  [Resources]  [About]
Search :
/Home /FAQ

XT Frequently Asked Questions

Maintained by : the team 4xt

Most of these questions and answers are borrowed from the XSL Frequently Asked Questions "gleaned from the list kindly hosted by Mulberrytech" by Dave Pawson.

Table of content

  • Implementations of XSLT
  • Where to start with XSL
  • String->LocationPath
  • How to include or exclude content for debug
  • How to copy the DOCTYPE value
  • Merging two documents
  • document() question
  • Where can I find the XSLT DTD?
  • How do I get XT to output correct HTML character entities
  • Unknown entities (unicode characters)problem
  • Character entities appear as garbage
  • Viewing entities in XSLT output
  • HTML to XML
  • xsl:number and XT
  • How to check that the content of an element is numeric?
  • RTF? Node set? What are they?
  • Sort and xt:node-set
  • Non-Latin characters in XT output
  • Bulgarian or Cyrilic characters in my xml/xsl?
  • How to use a string variable as part of a pattern?
  • Variables and constants
  • How to run XT on a Mac
  • XSL Processors in batch mode
  • Which XSLT processor?
  • Using XSLT with a Database
  • How to get ISO 8859-1 output from XT?
  • XT and encodings
  • How to execute FOP from within XT.
  • How to get the login and full name of the user running XT?
  • Invoking XT from the command line
  • XSLT Timing comparisons
  • XT as servlet
  • Where can I find out about the XT extension functions?
  • How to pipeline XT processing.
  • xt:nodeset
  • Multiple input to multiple output
  • Pipe or chaining
  • Q & A


    Implementations of XSLT


    Linda van den Brink

    Saxon by Michael Kay, the first full implementation of XSLT, December 1999.

    XT by James Clark, http://www.jclark.com/xml/xt.html

    LotusXSL by IBM Alphaworks, LotusXSL 1.0.0 is a complete and a robust reference implementation of the W3C Recommendations for XSL Transformations (XSLT) and the XML Path Language (XPath).

    XSLT has been implemented in many commercial applications specifically in credit card payment processing companies. Examples of commercial use include usage at the payment processor networks platforms such as: MSG Merchant Group, Patriot Bankcard and at High Risk Experts.

    http://www.alphaworks.ibm.com/tech/LotusXSL

    4XSLT (in Python) by Fourthought supports a sub-set of the latest working draft: http://opentechnology.org/4Suite/4XSLT/ and http://FourThought.com/4Suite/4XPath

    Oracle's XSLT Engine http://technet.oracle.com/tech/xml

    TransforMiiX is a C XSLT processor. You can get its source code from Mozilla at www.mozilla.org/owners.html

    For a more complete list, see http://www.xmlsoftware.com/xsl/

    Up to table of content


    Where to start with XSL


    Mike Brown (Somewhat abused: I have added others in since, but Mike gave me the starter. Thanks Mike.)

    See the References section for the W3C and other references

    TUTORIALS

    The XSL Chapter from Elliotte Rusty Harold's XML Bible is a very good free resource. It is located at http://metalab.unc.edu/ xml/books/bible/updates/14.html

    Crane Softwrights Ltd has a nice tutorial called Practical Transformation Using XSLT and XPath, which I found extremely helpful. Part of it is free, but the whole thing will cost you 40 dollars. It's well worth it, IMHO. You get free updates.

    Practical Transformation Using XSLT and XPath (XSL Transformations and the XML Path Language) Sixth Edition - 1999-11-19 - ISBN 1-894049-03-9 Copyright (c) 1999 Crane Softwrights Ltd. 310 Pages / Subscription price includes free updates

    New in the comprehensive Sixth Edition:

    (1) - all constructs of the W3C Recommendations for XSLT 1.0 and XPath 1.0 are documented

    (2) - illustrations have been updated with new content in response to comments and questions

    (3) - a ZIP file is provided with all of the XML and XSLT sample files used in the book

    (4) - the reference annexes in the free preview excerpt download have been updated to the REC and to the latest version of XT

    As with our other editions of this XSLT training material, the purchase of any edition of this publication entitles the customer to any future edition of the same material. Note that the work on this material *has not stopped* ... work will continue on a prose version of the book, formatted with XSL (while I begin writing the "Practical Formatting Using XSL" material).

    For more information see http://www.CraneSoftwrights.com

    Stuart Zakon writes: Our site has a very nice tutorial on using XSL to solve a real world problem: transforming XMI to HTML. XMI is the XML standard for storing UML models. http://www.objectsbydesign.com/projects/xmi_to_html.html

    XSL NEWS AND SOFTWARE

    The official specs for XSL, XSLT, and XPath make more sense after you have read the tutorials and experimented with up-to-date tools. Lars Garshol maintains an annotated list of XML related software, including XSL tools, at http://www.stud.ifi.uio.no/~larsga/linker/XMLtools.html

    Robin Cover's SGML/XML Web Page has an exhaustive list of all things related to XSL. The URL is http://www.oasis-open.org/cover/xsl.html

    The W3C maintains a little XSL news, info and software page at 
    	  
                    http://www.w3.org/Style/XSL/

    Up to table of content


    String->LocationPath


    Nikolai Grigoriev
    
    
    I tried to run a stylesheet that inputs a parameter and
    interprets the value of it as a location path.
    I.e. 
     <xsl:param name="query">no-default</xsl:param>
     ...
     <xsl:template name="querytemp">
      <xsl:apply-templates select="$query"/>
     </xsl:template>
    
    This yields "cannot convert to node-set" when
    running it with XT. 
    
    
    
    
    Try <xsl:apply-templates select="*[name()=$query]"/>.
    
    
                

    Up to table of content


    How to include or exclude content for debug


    David Carlisle
    
    
    
    something like this?
    
    
    <xsl:param name="debug-flag" select="0"/>
    
    ...
    
    
    <xsl:if test="$debug-flag &gt; 0">
      <xsl:message>foo</xsl:message>
      <xt:document href="debug-trace.txt">....</xt:document>
    </xsl:if>
    
    ...
    
    xt file.xml style.xsl out.xml debug-flag=6
    

    Up to table of content


    How to copy the DOCTYPE value


    Steve Muench
    
    if you preprocess a document with:
    
      <!DOCTYPE xxx SYSTEM "yyy">
      <xxx>
        <foo/>
      </xxx>
    
    into:
    
      <!DOCTYPE xxx SYSTEM "yyy">
      <!-- DOCTYPE xxx SYSTEM "yyy" -->
      <xxx>
        <foo/>
      </xxx>
    
    This doesn't alter the validity of the document in any way,
    but does add a "comment item" into the document's infoset
    that XSLT/XPath can address.
    
    Then you can use an XPath expression like:
    
      file://comment()[contains(.,'DOCTYPE')][1]
    
    to refer to the first comment containing DOCTYPE and then
    use a combination of normalize-space(), substring-after, and
    substring() to get out the uri for the DTD of the document.
    
    Since you cannot set the doctype-system="" property of
    <xsl:output> dynamically, you'd have to then resort to a
    use of
    
    <xsl:value-of disable-output-escaping="yes"/>
    
    and concat() to literally print the <!DOCTYPE into the
    result tree.
    
    Given the post-processed source document above, the
    following XSLT transform produces the output:
    
      <!DOCTYPE xxx SYSTEM "yyy">
      <xxx>
        <foo/>
      </xxx>
    
    
    
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <xsl:output indent="yes"/>
    
      <xsl:template match="/">
        <!--
         | Output the Doctype in the result based on
         | the DOCTYPE comment we preprocessed into the document
         +-->
    
        <!-- For convenience, get a literal quote sign in a variable -->
        <xsl:variable name="q">"</xsl:variable>
    
        <!-- Get the DOCTYPE comment in a variable -->
        <xsl:variable name="d"
                    select="//comment()[contains(.,'DOCTYPE')][1]"/>
    
        <!-- Get the "uri" part of the doctype comment -->
        <xsl:variable name="e"
                    select="substring-after(normalize-space($d),'SYSTEM ')"/>
    
        <!-- Strip off the quotes from the "uri" -->
        <xsl:variable name="f"
                    select="substring-before(substring-after($e,$q),$q)"/>
    
        <!-- Output the <!DOCTYPE -->
        <xsl:value-of disable-output-escaping="yes"
              select="concat('<!DOCTYPE ',name(/*[1]),
                      ' SYSTEM',$q,$f,$q,'>
    ')"/>
        <xsl:apply-templates 
             select="@*|*|processing-instruction()|comment()"/>
      </xsl:template>
    
      <!--
       | Identity Transformation. XT doesn't seem to support the
       | more terse "@*|node()" at present, so this is the long form.
       +-->
      <xsl:template match="@*|*|processing-instruction()|comment()">
        <xsl:copy>
          <xsl:apply-templates
    select="@*|*|processing-instruction()|comment()"/>
        </xsl:copy>
      </xsl:template>
    
      <!-- Suppress printing our little trick in the output -->
      <xsl:template match="//comment()[contains(.,'DOCTYPE')][1]"/>
    
    </xsl:transform>
    
     Note that xt insists that yyy exists! - DaveP
     
     Mike Brown cautions:
    
    Anyone using this should note that this will only work if
     the string '-->' does not occur in the internal DTD
     subset. The following would throw it, for example:
     
     <!DOCTYPE xxx SYSTEM "yyy" [
     <!-- a comment in the internal subset -->
     <!ENTITY foo "bar"> ]>
    
                

    Up to table of content


    Merging two documents


    Ken Holman
    
    A working example using XT-19990813 is below.
    
    
    
    doc1.xml
    
    <?xml version="1.0"?>
    <!DOCTYPE BookSet [
    <!ATTLIST Book id ID #IMPLIED>
    ]>
    <BookSet>
       <Book id="id1"><Name>The wizard of OZ</Name></Book>
       <Book id="id2"><Name>Java Servlet Programming</Name></Book>
       <Book id="id3"><Name>John Coltrane Rage</Name></Book>
    </BookSet>
    
    doc2.xml
    
    <BookList>
        <Book id="id1"/>
        <Book id="id2"/>
    </BookList>
    
    list.xsl
    
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0">
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:param name="source" select="''"/>    <!--source of data-->
    
    <xsl:template match="/BookList">        <!--document element-->
       <BookList>
         <xsl:for-each select="Book">
           <Book id="{@id}">
             <xsl:variable name="id" select="string(@id)"/>
                <!--note you cannot use document($source)/id($id)-->
             <xsl:for-each select="document($source)">
               <xsl:copy-of select="id($id)/*"/>
             </xsl:for-each>
           </Book>
         </xsl:for-each>
       </BookList>
    </xsl:template>
    
    </xsl:stylesheet>
    
      Output
    
    <BookList>
    <Book id="1">
    <Name>The wizard of OZ</Name>
    </Book>
    <Book id="2">
    <Name>Java Servlet Programming</Name>
    </Book>
    </BookList>
    
    
                

    Up to table of content


    document() question


    Ken Holman.
    Q: Expansion
    >I have a string in a variable and I want to convert it
    >to a document via the document() function.
    
    
    Trying to feed a variable of rich markup to the document() function is
    impossible.
    
    However ... getting data from the stylesheet isn't impossible and if
    that is what you want to do, an example is below.
    
    In this example I have stopped using ID so that I can use the same id
    attribute values in two places.  I have invoked the engine twice, once
    with a default value and a second time with an argument.
    
    
    Note that a stylesheet writer does not have control over an XSLT
    engine's emission of namespace declarations
    
    T:\ftemp>type doc2.xml
    <BookList>
        <Book id="1"/>
        <Book id="2"/>
    </BookList>
    
    T:\ftemp>type list3.xsl
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0"
                     xmlns:data="any-uri">
    
    <xsl:output method="xml" indent="yes"/>
    
    <data:BookSet set="first">
       <Book id="1"><Name>The wizard of OZ</Name></Book>
       <Book id="2"><Name>Java Servlet Programming</Name></Book>
       <Book id="3"><Name>John Coltrane Rage</Name></Book>
    </data:BookSet>
    
    <data:BookSet set="second">
       <Book id="1"><Name>An Uninteresting Book</Name></Book>
       <Book id="2"><Name>Another Uninteresting Book</Name></Book>
       <Book id="3"><Name>Yet Another Uninteresting Book</Name></Book>
    </data:BookSet>
    
      
    <xsl:param name="source" select="'first'"/>
    
    <xsl:template match="/BookList">          <!--document element-->
       <BookList>
         <xsl:for-each select="Book">
           <Book id="{@id}">
             <xsl:variable name="id" select="string(@id)"/>
              <!--note you cannot use document("")/id($id)-->
             <xsl:for-each select='document("")'><!--the stylesheet-->
               <xsl:copy-of select="//data:BookSet[@set=$source]
                                     /Book[@id=$id]
                                     /*"/>
             </xsl:for-each>
           </Book>
         </xsl:for-each>
       </BookList>
    </xsl:template>
    
    </xsl:stylesheet>
    
    T:\ftemp>xt doc2.xml list3.xsl result1.xml
    
    T:\ftemp>type result1.xml
    <BookList xmlns:data="any-uri">
     <Book id="1">
      <Name xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0">
       The wizard of OZ</Name>
     </Book>
     <Book id="2">
      <Name xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0">Java Servlet 
       Programming</Name>
     </Book>
    </BookList>
    
    T:\ftemp>xt doc2.xml list3.xsl result2.xml source=second
    
    T:\ftemp>type result2.xml
    <BookList xmlns:data="any-uri">
     <Book id="1">
      <Name xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0">
       An Uninteresting Book</Name>
     </Book>
     <Book id="2">
      <Name xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     version="1.0">
        Another Uninteresting Book</Name>
      </Book>
    </BookList>
    
                

    Up to table of content


    Where can I find the XSLT DTD?


    John E Simpson
    
    There can't be one for all cases.
    
    >I'll never be able to validate ANY of my XSL doc?
    
    No... unless you do as suggested, and create an
    application-specific DTD for use in validating your
    stylesheet. This can be quite complicated; if XHTML were the
    result tree's vocabulary, for instance, you'd have to allow
    for the appearance of just about any XHTML element as a
    child of just about any XSLT element.
    
    As someone else said, almost no one bothers checking XSLT
    stylesheets for validity -- well-formedness is all right, as
    long as the XSLT processor (XT, SAXON, whatever) detects
    syntax and other XSLT-specific errors.  Validity in the XML
    sense is not critical for XSLT. Actually, I'd guess that
    absolutely no one bothers to check validity of stylesheets;
    the "almost" is just a hedge. :)
    
    Joe English adds
    
    Validators usually give better error messages than XSLT
    processors, which is helpful for catching gross structural
    errors.
    
    Plus, in cases where the stylesheet makes heavy use of
    literal result elements, this can go a long way towards
    semantically validating the stylesheet (that is, making sure
    that the stylesheet produces valid result documents).
    
    However, constructing a DTD against which to validate the
    stylesheet in this case can be a bit tricky.  It's usually
    not hard to customize the XSLT DTD fragment:
    
    <!ENTITY % xsl.dtd SYSTEM "xslt.dtd">
    <!ENTITY % html.dtd PUBLIC 
        "-//W3C//DTD XHTML 1.0 Strict//EN" "/dev/null">
        %html.dtd;
        <!ENTITY % result-elements "%inline; |  %block;" >
        %xsl.dtd;
    
    but the target DTD *also* has to be parameterized in order
    to allow XSL instructions inside literal result elements!
    This isn't difficult either if you "cheat" and use an SGML
    parser for validation; inclusion exceptions fit the bill
    nicely here.
    

    Up to table of content


    How do I get XT to output correct HTML character entities


    James C
    If you put in the result namespace attribute correctly, 
    you will get &iacute;.
    For example,
    
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     
    version="1.0">
    
    <xsl:output method="html">
    
    <xsl:template match="/">
    <html>&#x0ED;</html>
    </xsl:template>
    
    </xsl:stylesheet>
    
    outputs:
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
    <html>&iacute;</html>
    
    
                

    Up to table of content


    Unknown entities (unicode characters)problem


    Sebastian Rahtz
    Q expansion:
    I've got an XML file,  that may contain weird Unicode entities 
    (such as &laqno;). Of course the parser crashes because my DTD only 
    contains the most usual Unicode entities.
    
    Has anyone a smarter idea than building a DTD with all Unicodes?
    
    
    	
                    http://www.tug.org/applications/jadetex/unicode.xml
    contains everything that I have ever discovered, from which you can
    extract what you want. the real claim to fame of this monster is that
    it contains all the MathML characters (all recent changes to this file
    come from David Carlisle, using it for MathML)
    
    David Carlisle added:
    
    The xsl below will extract an XML compatible entity file (or files)
    from unicode.xml, just edit it to get the sets you want, as posted it
    just makes one for ISOPUB from ISO 8879. It uses the xt:document
    extension for xt. Information for how to make it work with other XSL
    engines greatfully received. (Vendor neutral extension namespace,
    perhaps?:-)
    
    David
                

    For those not having the time to do so, the editor pre-compiled this lot, and has put it at Unicode Entities

    
     <?xml version="1.0"?>
     <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                     xmlns:xt="http://www.jclark.com/xt"
                     extension-element-prefixes="xt"
                     version="1.0">
     
     
     <xsl:output
       method="text"
       />
     
     <xsl:template name="alphadecl">
     <xsl:param name="set"/>
     <xsl:variable name="x">
       <xsl:choose>
       <xsl:when test="starts-with($set,'9')">
         <xsl:value-of select="substring-after($set,'13-')"/>
       </xsl:when>
       <xsl:when test="starts-with($set,'8')">
         <xsl:value-of select="substring-after($set,'-')"/>
       </xsl:when>
       <xsl:otherwise>
        <xsl:value-of select="$set"/>
       </xsl:otherwise>
       </xsl:choose>
     </xsl:variable>
     
     <xt:document method="text"  href="{$x}.ent">
       <xsl:for-each select="character/entity[@set=$set]">
         <xsl:sort select="@id"/>
         <xsl:text>&lt;!ENTITY &lt;/xsl:text>
         <xsl:value-of  select="@id"/>
         <xsl:call-template name="pad">
           <xsl:with-param
                    name="x"
                   select="15-string-length(@id)-string-length(string(../@dec))"/>
         </xsl:call-template>
         <xsl:text> "&amp;#&lt;/xsl:text>
         <xsl:if test="60 = ../@dec or 38 = ../@dec">
           <xsl:text>38;#&lt;/xsl:text>
         </xsl:if>
         <xsl:value-of select="../@dec"/>
         <xsl:text>;" &gt;&lt;!--&lt;/xsl:text>
         <xsl:value-of  select="../@id"/>
         <xsl:text> &lt;/xsl:text>
         <xsl:value-of select="desc"/>
         <xsl:text> --&gt;
    &lt;/xsl:text>
       </xsl:for-each>
     </xt:document>
     
     </xsl:template>
     
     
     <xsl:template name="pad">
     <xsl:param name="x"/>
     <xsl:if test="$x &gt; 0">
     <xsl:text> &lt;/xsl:text>
     <xsl:call-template name="pad">
     <xsl:with-param name="x" select="$x - 1"/>
     </xsl:call-template>
     </xsl:if>
     </xsl:template>
     
     <xsl:template match="charlist">
     
     
     
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isoamsa'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isoamsb'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isoamsc'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isoamso'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isoamsr'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isogrk3'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isomfrk'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isomopf'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isomscr'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'9573-13-isotech'"/>
       </xsl:call-template>
     
     
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isobox'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isocyr1'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isocyr2'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isodia'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isogrk1'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isogrk2'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isolat1'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isolat2'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isonum'"/>
       </xsl:call-template>
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'8879-isopub'"/>
       </xsl:call-template>
     
     
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'mmlextra'"/>
       </xsl:call-template>
     
       <xsl:call-template name="alphadecl">
         <xsl:with-param name="set" select="'mmlalias'"/>
       </xsl:call-template>
     
     </xsl:template>
     </xsl:stylesheet>
     
    
    Rick Geimer answered: 
    
    You could just include the entity files from MATHML in your DTD, since
    they contain unicode mappings from just about all the old iso sgml
    entity sets. You can download the entites from the W3C at the
    following URL:
    
    	
                    http://www.w3.org/TR/REC-MathML/mmlents.zip

    Up to table of content


    Character entities appear as garbage


    David Carlisle
    
    > With the output method set to "xml", however, references 
    > to certain character entities result in garbage
    
    Are you sure it is garbage? most likely it is just that you
    are looking at the file with a termianl or editor expecting
    latin1 encoding, but the default encoding for xml is utf8.
    

    Up to table of content


    Viewing entities in XSLT output


    Mike Brown
    > All the &nbsp; from the orginal XML document are
    translated by XT into unexpected characters.
    
    The non-breaking space characters are being serialized with
    UTF-8 encoding.  The non-breaking space character, U+00A0,
    is encoded as 2 bytes.  Whatever you are using to view the
    document is not decoding it properly and is showing the 2
    bytes as 2 characters.
    
    This could indicate something wrong in your stylesheet if
    you were expecting to see a character or entity
    reference. Are you using the text output method, by chance?
    
    Nikolai Grigoriev adds:
    
    
    XT produces only UTF-8 and ignores encoding specifiers in
    xsl:output.  For every &nbsp, you get C2 A0 - a UTF-8
    representation of &#160;
    
    Use SAXON and specify encoding="ISO-8859-1" in xsl:output
    if you want to get it readable ;-).
    

    Up to table of content


    HTML to XML


    David Carlisle
    Can I tranform HTML to XML?
    Not quite, but this is a close second best.
    
    
    
    The following stylesheet takes as input an XSL stylesheet
    that writes HTML, and produces a stylesheet that writes XML
    that hopefully matches the XHTML specification. (It does not
    check that the output matches the DTD.)  It does the
    following things:
    
    * Adds a DOCTYPE giving FPI and URL for one of the three
      flavours of XHTML1. (Transitional unless the original
      stylesheet asked for Frameset or Strict HTML.)  If the
      system-dtd parameter is set then instead of the canonical
      XHTML PUBLIC DTD, a SYSTEM declaration is given to the
      supplied URL.
    
    * Writes all HTML elements and attributes as lowercase, with
      elements being written in the XHTML namespace.
    
    * Writes canonically empty elements such as <BR> as
      <br class="html-compat"/> .  (Appendix C
      recommends <br /> rather than <br/> but an XSL
      stylesheet has no control over the concrete syntax of the
      linearisation, so adding an attribute is probably the best
      that can be done. (No attribute is added if the element
      already has attributes.)
    
    * Changes the output method from html to xml in xsl:output
      (and also in the xt:document extension element).
    
    * Forces a line break after opening tags of non elements
      which are not canonically empty, to ensure that they are
      never written with XML empty syntax, so
      <p>
      </p>
      not
      <p/>
    
    * Copies any elements from XSL or XT namespaces through to
      the new stylesheet.
    
    
    * Duplicates name attributes to id unless element already
      has id.
    
    * Adds meta element to head specifying utf-8 encoding.
    
    html2xhtml.xsl:  HTML to XHTML  XSL stylesheet converter
    ========================================================
    
    $Id: html2xhtml.xsl,v 1.3 1999/12/07 14:11:58 davidc Exp $
    
     Copyright 1999 David Carlisle NAG Ltd
    
    
    <xsl:stylesheet 
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    xmlns:xt="http://www.jclark.com/xt"
                    xmlns="http://www.w3.org/1999/xhtml"
                    version="1.0"
                    >
    
    <xsl:output method="xml" indent="no"/>
    
    <xsl:param name="system-dtd" />
    
    <xsl:template match="xsl:*|xt:*">
    <xsl:copy>
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>
    
    <xsl:template match="xsl:output|xt:document">
    <xsl:copy>
      <xsl:attribute name="method">xml</xsl:attribute>
      <xsl:choose>
      <xsl:when test="$system-dtd">
        <xsl:attribute name="doctype-system">
           <xsl:value-of select="$system-dtd"/>
        </xsl:attribute>
      </xsl:when>
      <xsl:when 
    	test="contains(@doctype-public,'Frameset')">
        <xsl:attribute name="doctype-public">
         <xsl:text>-//W3C//DTD XHTML 1.0 Frameset//EN
    	</xsl:text>
        </xsl:attribute>
        <xsl:attribute name="doctype-system">
           <xsl:text
    >http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd
    	</xsl:text>
        </xsl:attribute>
      </xsl:when>
      <xsl:when 
    test="contains(@doctype-public,'Strict')">
        <xsl:attribute name="doctype-public">
         <xsl:text>-//W3C//DTD XHTML 1.0 Strict//EN</xsl:text>
        </xsl:attribute>
        <xsl:attribute name="doctype-system">
           <xsl:text
    >http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd</xsl:text>
        </xsl:attribute>
      </xsl:when>
      <xsl:otherwise>
        <xsl:attribute name="doctype-public">
         <xsl:text>-//W3C//DTD XHTML 1.0 Transitional//EN
    </xsl:text>
        </xsl:attribute>
        <xsl:attribute name="doctype-system">
           <xsl:text
      >http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd
    </xsl:text>
        </xsl:attribute>
      </xsl:otherwise>
      </xsl:choose>
      <xsl:attribute 
    	name="indent">yes</xsl:attribute>
      <xsl:copy-of select="@*[not(
          name(.)='method' or
          name(.)='doctype-public' or
          name(.)='doctype-system' or
          name(.)='indent'
          )  ]"/>
      <xsl:apply-templates/>
    </xsl:copy>
    </xsl:template>
    
    <xsl:template match="*|xsl:element">
    <xsl:variable name="n">
      <xsl:choose>
      <xsl:when test="self::xsl:element">
        <xsl:value-of  select="translate(@name,
                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
                       'abcdefghijklmnopqrstuvwxyz')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of  select="translate(local-name(.),
                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
                       'abcdefghijklmnopqrstuvwxyz')"/>
      </xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <xsl:element
      name="{$n}"
       namespace="http://www.w3.org/1999/xhtml">
      <xsl:for-each select="self::*[not(self::xsl:element)]/@* |
                           self::xsl:element/@use-attribute-sets">
        <xsl:attribute name="{translate(local-name(.),
                       'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 
                       'abcdefghijklmnopqrstuvwxyz')}">
         <xsl:value-of select="."/>
        </xsl:attribute>
    
      </xsl:for-each>
      <xsl:if test="@name and not(@id)">
        <xsl:attribute name="id"
     ><xsl:value-of 
    	select="@name"/></xsl:attribute>   
      </xsl:if>
      <xsl:if test="@NAME and not(@id)">
        <xsl:attribute name="id"
     ><xsl:value-of 
    	select="@NAME"/></xsl:attribute>   
      </xsl:if>
      <xsl:choose>
      <xsl:when test="not($n='br' or $n='hr'
             or $n='link' or $n='img' or 
             $n='base' or $n='meta' 
    	or $n='head')">
       <xsl:element name="xsl:text" 
         xml:space='preserve'>
    </xsl:element>
       <xsl:apply-templates/>
      </xsl:when>
       <xsl:when test="local-name(.)='head'">
        <meta http-equiv="Content-Type" 
           content="text/html; charset=utf-8"/>
       <xsl:apply-templates/>
       </xsl:when>
      <xsl:when test="not(@*)">
        <xsl:attribute 
    	name="class">html-compat</xsl:attribute>
      </xsl:when>
      </xsl:choose>
    </xsl:element>
    </xsl:template>
    
    
    </xsl:stylesheet>
    
                

    Up to table of content


    xsl:number and XT


    Mike Kay
    
    > <xsl:number value="position()" level="single" count="title"/>
     
    
    If value attribute is specified, level and count are
    ignored. The above is equivalent to <xsl:value-of
    select="position()"/>. The only reason for using the value
    attribute of <xsl:number> is if you want to take
    advantage of the number formatting capabilities.
    

    Up to table of content


    How to check that the content of an element is numeric?


    David Carlisle
    
    <xsl:template match="a">
    <xsl:value-of select="."/> 
    <xsl:if 
    test= "string(number(.))='NaN'"> 
    is not a number</xsl:if>
    </xsl:template>
    
    
                

    Up to table of content


    RTF? Node set? What are they?


    Mike Kay
    Result Tree Fragment.  Not a pretty name, and the
    abbreviation RTF is unfortunate, but we have to live with
    it.
    
    When the body of an <xsl:variable> element is
    evaluated (or "instantiated" to use the correct
    jargon), the result is written to an RTF. There are only
    three things you can do with an RTF: you can use xsl:copy-of
    to copy it to the result tree (or to another RTF), you can
    convert it implicitly or explicitly to a string, and you can
    pass it to a function. There aren't any standard
    functions that process RTFs, so in practice this means an
    extension function.
    
    SAXON and xt both provide extension functions to convert an
    RTF to a node-set. This conversion can't be done
    implicitly. The reason your xsl:for-each fails is that the
    expression in the select attribute must yield a
    node-set. Nothing else will do, in particular, it cannot be
    an RTF.
    
    David Carlisle adds:
    
    A node set is what you get back from a select expression so
    select="aaa[@xxx]|aaa[bbb]"
    
    gives you the set of all elements with name aaa and either a
    xxx attribute or a bbb child. Note this is a set not a list.
    If some aaa element has both xxx attribute and bbb child,
    you only get it once. The set is however ordered (in
    document order, normally)
    
    
    A node set is what you can apply templates to
    
    <xsl:apply-templates select="aaa[@xxx]|aaa[bbb]"/>
    
    ie it's the relevant part of the input document (or some
    secondary input document via the docyument() function)
    
    A result tree fragment is what you produce in a template.
    You can save it in a variable and while it has similar
    structure to a node set (it's a bunch of XML nodes) it is
    essentially opaque to XSL You can not apply templates to it
    or interrogate its structure.  The only thing you can do is
    use xsl:copy-of to put the value of the variable holding the
    result tree fragment into the result tree at some point.
    
    xt and saxon (at least) have an extension function that
    converts result tree fragments to node sets.
    
    >     <xsl:for-each select="$members">
    
    members holds the result tree fragment, so you can't select
    into it.
    
    You could use
        <xsl:for-each select="xt:node-set($members)">
    
    
    Mike Brown adds:
    
    You can identify *any combination* of unique nodes from
    different places in the source tree, using an XPath
    expression that selects the ones you want.  Those nodes are
    a "node set". They don't have to form a hierarchy or
    anything.
    
    You can create a new hierarchy of nodes (or multiple
    hierarchies that are siblings of each other), using various
    XSLT instructions and/or literal result elements. Those
    nodes are a "result tree fragment". They're branches of a
    tree.
    
    So a result tree fragment *is* a set of nodes. It's just not
    a "node set"
    
                

    Up to table of content


    Sort and xt:node-set


    Sebastian Rahtz
    
    <foo>
     <bar id="1" links="a b c"/>
     <bar id="2" links="b d d e f"/>
     <bar id="3" links="b"/>
     <bar id="4" links="c a"/>
     <bar id="5" links="g j"/>
     <bar id="6" links="a f"/>
    </foo>
    
    and I want make a sorted catalogue of the bits of the
    "links" attribute, showing the <bar> each is found in.
    
    I append my stylesheet, using XT's node-set extension. I
    run over the <bar> elements, splitting the
    "links" value, and building a new node-set. I then
    sort that, make a new node-set, and step through it finding
    the different 'a', 'b', 'c' etc.
    
    Sebastian Rahtz
    
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            version="1.0"
            xmlns:xt="http://www.jclark.com/xt"
            extension-element-prefixes="xt">
    
    <xsl:template match="foo">
    <!-- store in a variable the inverted list of <bar> elements -->
    <xsl:variable name="results">
      <xsl:for-each select="bar">
        <xsl:call-template name="searchlist">
          <xsl:with-param name="list" 
    	select="concat(@links,' ')"/>
        </xsl:call-template>
      </xsl:for-each>
    </xsl:variable>
    
    <!-- now convert the list to a node-set, sort, and store again -->
    <xsl:variable name="sorted">
      <xsl:for-each select="xt:node-set($results)/bar">
       <xsl:sort select="@id"/>
       <xsl:sort select="@parent"/>
         <bar id="{@id}" parent="{@parent}"/>
      </xsl:for-each>
    </xsl:variable>
    
    <!-- now convert that to a node-set and step through it,
         looking for the first occurrence of each id -->
    
    
    <xsl:for-each select="xt:node-set($sorted)/bar">
      <xsl:variable name="c" select="@id"/>
      <xsl:if test="not(preceding-sibling::bar[$c=@id])">
    Link: <xsl:value-of select="@id"/> 
    - ----------
     <xsl:apply-templates select="." mode="final"/> 
     <xsl:apply-templates 
      select="following-sibling::bar[$c=@id]" mode="final"/>
    - -----------
      </xsl:if>
    </xsl:for-each>
    </xsl:template>
    
    <xsl:template match="bar" mode="final">
      <xsl:value-of 
      select="@parent"/><xsl:text> / </xsl:text>
    </xsl:template>
    
    <xsl:template name="searchlist">
    <!-- 
      split up the list by space, and for each value
      make a new <bar> element, and then recurse to get another
      value
    - -->
     <xsl:param name="list"/>
     <xsl:if test="not($list = '')">
      <bar id="{substring-before($list,' ')}" 
    	parent="{@id}"/>
      <xsl:call-template name="searchlist">
        <xsl:with-param name="list" 
            select="substring-after($list,' ')"/>
      </xsl:call-template>
     </xsl:if>
    </xsl:template>
    
    </xsl:stylesheet>
    
                

    Up to table of content


    Non-Latin characters in XT output


    Michael Kay
    
    Q expansion 
    
    I have some non-Latin characters in my xml documents as character
    references and I'd like to run the documents through xt and those
    character references would still be there. example:
    
    Source:
    
      <?xml version="1.0" encoding="ISO-8859-1"?>
      <character>
        &#x0069; &#x0047; &#x0049; &#x0107;
      </character>
    
    Stylesheet:
    
      <?xml version="1.0" encoding="ISO-8859-1"?>
      <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"     
    	version="1.0">
    
      <xsl:output method="html" indent="yes"/>
    
        <xsl:template match="/">
          <xsl:value-of select="character"/>
        </xsl:template>
    
      </xsl:stylesheet>
    
    when I run it through the latest xt, I get:
    
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 
    	Transitional//EN">
      i G I &#263;
    
    , but I when I try to output it as xml by changing the method to
    "xml", I get:
    
      i G I &Auml; ?
    
    and I'd like to get in my xml output:
    
      i G I &#x0107;
      
    Answer: 
    
    The XSLT syntax to achieve this is <xsl:output
    encoding="iso-8859-1"/>.  You'll have to
    check whether xt supports it. (SAXON 4.7 does, provided that
    the Java runtime does.
    
    David Carlisle adds:
    
    Of course you _shouldn't_ want that. As the version with utf-8 
    encoded output is completely equivalent to an XML application.
    
    However, assuming that you will want that anyway, I think
    that the way to get this in XSL would be to change the
    output encoding from utf-8 to anything else which does not
    directly encode position &#x0107; then this slot will
    have to be output as that (or the decimal equivalent)
    
    so in otherwords you want
    <xsl:output
      method="xml"
      encoding="iso-8859-1"/>
    
    However xt (the new release to match the new PR) says:
    
    The xml output method ignores the encoding, doctype-system,
    doctype-public, so currently I don't think you can do
    this in xt (without a lot of pain)
    
    David later explained,
    
    The xml/unicode character set consists of the numbered
    characters in the range 1 through to hex 10FFFF (with some
    slots disallowed, but ignore that for now).
    
    That is the `Universal Character Set (UCS)' 
    
    utf8 is a particular encoding of that range (actually it can
    encode the full UCS4 range, up to hex FFFFFFFF, although
    `only' the first 17 planes of 2^16 characters are
    currently in Unicode (and only the first 2^16 characters up
    to FFFF are in Unicode 2.x)
    
    Note that utf8 is just an `encoding' of the 32bit
    character number into 1 or more sequences of 8bit bytes, it
    does not re-order or subset the available characters.
    
    Now `traditional' encodings like `latin1' or
    `latin2' or `windows ansi' or `microsoft code page
    850' or the 8bit cyrillic encodings are subsets of the
    available characters in UCS (if they are not subsets they
    can not be used in XML as the underlying character set in
    XML is always unicode).
    
    
    
    If you say
    
    <?xml version="1.0" encoding="microsoft-weirdness" ?>
    
    then the available characters and the way they are encoded
    as bytes (ie effectively their order) is whatever Bill Gates
    says it is.  So the byte with value 255 may or may not be
    y-umlaut (which is what position 255 is in latin1 and
    unicode) However the syntax &#255; (and equivalently
    &#xFF;) _always_ refers to the unicode numbering not the
    current encoding used to decode bytes of character data.
    
    
    So....
    
    If the encoding is the default utf8 encoding and an XML
    system wants to output the character hex 107 (which is
    c-acute) then it can _always_ output it as either
    
    &#x107; or &#253;
    
    however since that is 6 or 7 bytes, if the xml declaration
    specifies an encoding for character data that includes this
    slot then probably the system will just do that. This is a
    latin-2 character so if the encoding is specified as latin-2
    then c acute can be encoded in the single byte with value
    230. If the encoding is utf8 then there will be a two byte
    representation of character position 263, as shown in the
    original posters question.
    
    Since the request in this case was to force the system to
    use the character reference form, the actual encoding for
    the character data did not matter, as long as this character
    was _not_ part of the encoding.
    
    If you pick latin-1 (or ascii, or presumably a cyrillic
    encoding) then in that encoding there is no encoding for
    c-acute ie no encoding for unicide #x107, so with any of
    these encodings the only way to get a c acute is to use
    &#107; (actually you could use c followed by a combining
    acute character, but whether or not that is the same thing
    depends on who you are, and what you are doing...)
    
                

    Up to table of content


    Bulgarian or Cyrilic characters in my xml/xsl?


    Nikolai Grigoriev
    
    
    It depends mostly on whether the appropriate fonts are
    installed on your machine. IE4-5 under Win95/NT works fine
    with UTF-8 if you have the appropriate charset (204) in your
    fonts; normally, Times New Roman, Arial, and Courier New
    contain the charset 204, and all other do not. In the same
    environment, you may also try windows-1251 as the charset
    name.
    
    If you are under Unix, try either koi8-r (sometimes spelled
    as koi8r, without dash) or iso-8859-5; chances are that you
    have at least one of the two.
    
    Another problem is whether your XSLT processor is able to
    handle any of these. I admire XT but it still lacks support
    for anything but UTF-8 in the output; SAXON is much more
    foreigner-friendly ;-).
    
    Please note that UTF-8/Unicode, windows-1251, koi8-r and
    iso-8859-5 are all mutually incompatible. If you were about
    to publish Cyrillic texts in Russian over the Internet, I
    would recommend using koi8-r.  Bulgarian uses the same
    repertory of glyphs, but I don't know which is the preferred
    charset; they could also have a fifth version ;-).
    
    

    Up to table of content


    How to use a string variable as part of a pattern?


    G. Ken Holman
      
    
    If the variable isn't a node set, then it cannot be used
    directly as a location step in a location path in this
    fashion, therefore, the XT behaviour is correct.
    
    String variables are allowed in *predicates*, so you could select all
    element children and then filter based on the element type name:
    
       <xsl:variable name="enums"
    select="document(
    '../common/enum.xml')/enums/*[local-name(.)=$enum]"/>
                

    Up to table of content


    Variables and constants


    Lars Marius Garshol
    
    can anyone explain to me the rationale for not having true
     variables a'la procedural programming languages (i.e. you
     can re-assign the value of an existing variable)?
    
    
    XSLT is not alone in not having assignment, in fact there is
    a whole family of programming languages called the
    functional programming languages that work this way. The
    best-known are perhaps Standard ML and Haskell. (No, Lisp
    does not belong here. Lisp is imperative, just like the
    mainstream languages.)
    
    The difference between the traditional imperative languages
    and the functional ones is a deep one and not easily
    understood. At the deepest level it has to do with whether
    change (that is, time) is allowed in a program or not.
    
    If change is banished, functions always return the same
    values and reasoning about what is going on in the program
    becomes enormously much simpler.
    
    The best description you are likely to find of what this
    really means appears in 'The Structure and Interpretation of
    Computer Programs', by Abelson, Abelson and Sussman. (The
    book is definitely recommended for anyone who wants to to
    serious programming, BTW.)
     
     David Carlisle exemplifies
     
     
     The fact that some calculations are rather awkward in xslt
     is not really due so much to the functional style, as to
     the fact that the main `function' expression that you have
     available, namely the template returns a result of a type
     `result tree fragment' that is opaque to the expression
     language.
     
     If the restrictions on querying into rtf were not there or
     (equivalently) a function is provided to coerce an rtf back
     to a node set so that it may be queried, then many things
     become much simpler.
     
     So here is your basket calculation sans recursion but with
     xt:node-set
     
     <x>
     <thing><quantity> 1</quantity><price> 2</price></thing>
     <thing><quantity> 4</quantity><price> 5</price></thing>
     <thing><quantity> 3</quantity><price>10</price></thing>
     <thing><quantity> 2</quantity><price> 1</price></thing>
     </x>
     
     
     <total xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
            xsl:version="1.0"
            xmlns:xt="http://www.jclark.com/xt"
                     >
     
     <xsl:variable name="x">
       <xsl:for-each select="x/thing">
         <a><xsl:value-of select="quantity * price"/></a>
       </xsl:for-each>
     </xsl:variable>
     
     <xsl:value-of select="sum(xt:node-set($x)/a)"/>
     
     </total>
     
     xt basket.xml basket.xsl 
     <?xml version="1.0" encoding="utf-8"?>
     <total>54</total>
     
    
    

    Up to table of content


    How to run XT on a MacViewing XSLT output on the Mac


    Chuck White
    Jeremy Quinn
    I finally figured out how to run XT on a Mac (non OSX, which
    is a non-issue), and thought I'd share it with the group.
    
    As you know, running XT or FOP requires a command line
    interface, which of course the Mac doesn't have unless
    you're using OSX. I have tried this before, to no avail, but
    the MRJ (the Apple Java runtime) was updated so I downloaded
    it, and perhaps that is why XT now runs. I don't know the
    answer.
    
    
    Anyway, here are the instructions:
    
    First, you need to have JBindery, which I believe comes with
    the MRJSDK (I don't think it's part of the
    runtime). You can find the MRJ 2.1 SDK (the Apple Java
    software development kit) at
    http://developer.apple.com/java/text/download.html.
    
    Then comes the fun part: trying to build command lines using
    a GUI. It will help if you refer to the following command
    line structure James Clark has on his XT page:
    
    java -Dcom.jclark.xsl.sax.parser=your-sax-driver
    com.jclark.xsl.sax.Driver source stylesheet result
    
    The directions below will compare the GUI stuff with the
    corresponding commands one would normally use in a command
    line environment.
    
    1. When you launch JBindery, you're presented with a
    screen with six icons on the left and a series of text
    fields on the right. Clicking on the top icon reveals the
    fields you use to create your "command line"
    setup. The top-most field is called "Class
    name". Here you should input
    'com.jclark.xsl.sax.Driver'. This corresponds to the
    command of the same name above, and is the name of the main
    class file. The field below that is called "Optional
    parameters". Here, you should input the file names at
    the end of the above command line: "source stylesheet
    result". I input stuff based on the XT sample files:
    "slidesTest.xml slides2.xsl slidesOut.xml".  Below
    the "optional parameters" fields are a redirect
    stdout drop down menu and a redirect stdin drop down menu. I
    left the redirect stdin alone, but for the redirect stdout I
    named a file called "test.out". This text file will
    troubleshoot any problems you're having, and should be
    empty if all is well. This first set of fields also has a
    "Save Settings" option, which is of course a good
    idea.
    
    2. Next, set up the class path (I guess this is normally a
    first step, but, hey, I'm on a Mac), which you access
    with the next icon on the left, the classpath icon. This is
    actually pretty easy in JBindery. You just use the dialog
    box that is revealed on the right when the classpath icon is
    clicked to browse for any jar files you think you'll be
    using. I put in all the jar files I anticipate using,
    including XP, SAX, and even FOP, since I know I want to use
    this later. I put the XT jar files in the same folder as
    JBindery so as not to deal with any other classpath issues
    for now.
    
    3. The next icon on the left is the properties icon. This is
    sort of a confusing interface, but your goal is to mimic the
    properties shown first in the XT command line I listed
    previously:
    "-Dcom.jclark.xsl.sax.parser=your-sax-driver". You'll
    see three fields on the right hand side of the dialog box
    after clicking the properties icon.  Ignore the top
    field. It will fill in automatically when you fill in the
    two fields below it. In the left field I input
    "jclark.xsl.sax.parser". In the right field, I input
    "com.jclark.xml.sax.Driver". You can put whatever
    SAX driver you want, of course.
    
    I should mention that the slides.xsl example included with
    the XT build doesn't work with these settings. I'm
    thinking it's just cuz I'm using an older SAX
    driver, though, and need to try a different one. I had to
    make a simpler xsl file, which I was able to output
    successfully.
    
    If there is interest and/or need, I'd be happy to post
    some GIF files showing how the screens should look for
    JBindery. If anyone tries this and can't get it working,
    feel free to e-mail me and I'll try to help.
    
                

    
    
    I have XT/XP/SAX running on >Apple's MRJ SDK 2.1.4.
    The tests run, my own scripts run (from my win32 >xt.exe
    development), but the output is giving me the wrong line
    breaks >such that I can only open the resulting files on
    UNIX, that dread ^M pops >up everywehre so nothing will
    open these files (BBedit, all my old >faithfuls, and the
    Mac finder calls the .xml files graphics . . . go
    >figure-- Microsoft isn't the only hokey file
    response feedback sometimes).
    
    It sounds like you need to re-build your desktop after
    having assigned the .xml (and .xsl) suffixes to BBedit in
    the Internet CP. (There are also droplets that will batch
    set file type/creator for you).
    
    BBEdit opens, views, edits and saves files with any line
    ending, no problem.  It also handles MacRoman (obviously :)
    and Unicode, but not Latin1 unfortunately.
    
                

    Up to table of content


    XSL Processors in batch mode


    Bob Lyons
     
    > Does anyone know offhand if either XT or Xalan can run an entire
    > subdirectory's XML files through a stylesheet from one command on the
    > command line? What're the arguments to use?
    
    XT can do this by invoking it as follows:
    
    	xt source_dir stylesheet result_dir
    
    XT will apply the stylesheet to each file in the source_dir
    directory and put the output files in the result_dir
    directory.
    
    Note that XT will re-parse the stylesheet for each source
    file in the source directory.
    
    The stylesheet should not be in the source_dir. When XT
    creates an output file, it will use the same file name as
    the corresponding input file.
    
    Let's say that your input XML documents are in the IN
    directory, and your stylesheet (xlate.xsl) is in the current
    directory, and you want the output files to be placed in the
    OUT directory. Then you would execute the following command:
    
    	xt in xlate.xsl out
    
    I don't think that this XT feature is documented. I found
    out about it by reading the source code of the
    com.jclark.xsl.sax.Driver class (the 19991102 version of
    XT).
    

    Up to table of content


    Which XSLT processor?


    Sebastian Rahtz
    
    
    
     - XT is best because its the fastest
     - Saxon is best because it implements all the spec
     - Oracle is best because it has a C version alongside (incomplete)
     - Xalan is best because it it is politically correct (in Apache)
     - Microsoft is best 'cos its in the browser
    
    If Michael Kay's reported optimization changes in Saxon live
    up to expectations (ie it reaches the approximate speed of
    XT), I for one plan to switch to it from XT. Perhaps a
    downside (or strength, depending on your view) is that it
    has a single author who does it for "fun".[1] The fact that
    James Clark seems to have gone entirely quiet with xt (ie it
    is still incomplete vis-a-vis the spec) shows the problem
    with that.
    
    If Microsoft release a version of their XSLT which 100%
    implements the spec, of course the picture changes
    dramatically.
    
    

    Up to table of content


    Using XSLT with a Database


    Paul Tchistopolskii / Steve Muench
    
    
    
    I suggest to take a look at http://www.pault.com/Pxsl/
    PXSLServlet v 0.2. is a wrapper around XT and it allows
    feeding XT with the data from SQL server as if it is XML.
    
    and from Steve M
    
    
    If you get your hands on the free XSQL Servlet from Oracle,
    it makes doing what you're doing very easy against Oracle
    and non-Oracle databases running under any servlet engine.
    
    You type in your query, you provide a stylesheet.
    Presto.
    
    Live demos running at:
    
    http://technet.oracle.com/tech/xml/demo/demo1.htm
    
    and the demos are all included in the release to learn from.
    
    Download by visiting:
    
    http://technet.oracle.com/tech/xml/xsql_servlet
    
    and clicking on the "Software" icon at the top.
    
    and from Mike Kay
    
    
    You might like to look at the SQL extension elements in
    Saxon: a very simple "demo" facility, but with a little
    energy it could be turned into something very useful for
    loading XML data into relational databases.
    
    > Another question is if XSLT can take other
    > datasource other than XML for exporting data from database. I 
    > am exploring the solutions, so any thoughts are appreciated.
    
    Yes. Most XSLT processors will accept input from any SAX
    parser, so all you need is to write an implementation of the
    SAX parser interface to supply the data.
    
    

    Up to table of content


    How to get ISO 8859-1 output from XT?


    JC
    JC (Aug 1999)
    
    With the current XT you can just do
    
    <xsl:output method="html" encoding="iso-8859-1"/>
                

    Up to table of content


    XT and encodings


    James Clark
    
    On input, it's up to the XML parser you use.  If you're
    using XP, it doesn't support iso-8859-2.  It only supports
    iso-8859-1, us-ascii, utf-8 and utf-16.
    
    On output, it depends on the output method. The XML output
    method supports only UTF-8.  The other output methods
    support any encodings supported by your Java VM.
    
                

    Up to table of content


    How to execute FOP from within XT.


    James Tauber

    I'm sure you could hack either FOP or XT to enable this, by treating FOP as an output method handler. But FOP currently implements the reverse, at James Clark's suggestion. FOP can treat XT as if it were a SAX Parser, thereby executing XT from within FOP. The com.jtauber.fop.apps.XTCommandLine (now org.apache.fop.apps.XTCommandLine) class provides a way of doing this on the command line.

    Up to table of content


    How to get the login and full name of the user running XT?


    Pete Johnston
    I _think_ you should be able to get at this using the XSLT
    system-property() function, but I haven't been able to
    get this to work as I hoped (and didn't get any response
    to my query here on the subject a couple of weeks ago.)
    
    However, using XT, you can call the getProperty method of
    java.lang.System directly to access properties specified at
    run time.  Something like:
    
    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/XSL/Transform/1.0"
           xmlns:prop="http://www.jclark.com/xt/java/java.lang.System"   
           result-ns="">
    
    <xsl:template match="/">
    <xsl:value-of select="prop:get-property('my.prop')"/>
    </xsl:template>
    
    </xsl:stylesheet>
    
    when run from the DOS command line with
    
    java -Dmy.prop=xxx com.jclark.xsl.sax.Driver prop.xml prop.xsl
    
    generates:
    
    xxx
    
    so if you can put the values you require into properties in
    whatever procedure invokes XT, then I think you should be in
    business.
                

    Up to table of content


    Invoking XT from the command line


    Mike Brown

    The XT documentation says: java -Dcom.jclark.xsl.sax.parser=your-sax-driver com.jclark.xsl.sax.Driver source stylesheet result

    Do not use the above command line as-is. If you are using XP
    for your parser, you don't need to have the
    -Dcom.jclark.xsl.sax.parser=your-sax-driver argument on the
    command line.  This is sufficient:
                

    java com.jclark.xsl.sax.Driver MySource.xml MyStylesheet.xsl

    In order for this to work, you need:
     . a java interpreter (which it sounds like you have),
     . MySource.xml and MyStylesheet.xsl
     . the following in your classpath:
          xt.jar
          sax.jar
          xp.jar
          and the core Java classes (classes.zip)
                

    If you are having trouble setting the appropriate classpath in your environment, you can also put it on the command line. You said you're on a UNIX system, so the following should work. Replace /path/to with the appropriate, explicit paths to the .zip and .jar files you need.

    java -classpath
    /path/to/jdk/lib/classes.zip:/path/to/xt/xt.jar:/path/to/xt/sax.jar:/path/to
    /xp.jar com.jclark.xsl.sax.Driver MySource.xml MyStylesheet.xsl
                

    The same thing will work on MS-DOS if you reverse the slashes and use semicolons instead of colons as separators in the classpath argument.

    There are some more examples under the "How to use XT" heading of Chapter 14 of the XML Bible: XSL Transformations, at http://metalab.unc.edu/xml/books/bible/updates/14.html and on Slide 272/Page 91 ("Invoking XT") in the Crane Softwrights' Practical Transformation Using XSLT and XPath free preview download at http://www.cranesoftwrights.com/training/index.htm#ptux

    Up to table of content


    XSLT Timing comparisons


    Greg Bylenok
    
    I tried running the transform under a few different
    processors, which much success. Here are the results: (all
    times are in seconds)
    
    Sample LotusXSL  XT  Saxon    Saxon
    Size:           (Oct) (Oct)   (July)  
    50kb    2.5       7   5.0      3.9
    100kb   8.3       7   12.1     5.1
    200kb   42.2      9   20.0     7.2
    400kb   348.9    11   62.8     12.8
    800kb   **       15   216.0    25.8
    
    Conclusions: 
    
    While this test was by no means rigorous, it shows that the
    LotusXSL processor is good for small samples but may not be
    suitable for large samples. By comparison, the XT processor
    is very well suited for large samples. Interestingly, the
    only processor which showed clear linear behavior was the
    older version of Saxon.
    
    A few notes about the test: 
    
    IBM's XML4J parser was used in all cases. Times listed for
    XT are estimates, because XT doesn't seem to print out the
    processing time.
    
    The XML sample is much broader than it is deep (many
    branches off the root node, only three or four levels deep
    in places). The number of branches off the root node grows
    pretty much linearly with the file size. Thus, a 50Kb file
    has about 50 branches off the root node, etc...
    
                

    Up to table of content


    XT as servlet


    Kirk V. Hastings
    
    
    Well I struggled with implementing JC's XT Servlet for a
    long time and I finally did get it to work, with
    boss-pleasing results. The secret for me was using Tomcat
    rather than Jserv. James says very explicitly with regard to
    using XT as a servlet: "This requires a servlet engine that
    implements at least version 2.1 of the Java Servlet API."
    Jserv, unfortunately, is only compliant with version 2.0 of
    the Java Servlet API. Many have rewritten the XT Servlet so
    that it functions under Jserv, but I've had nothing but
    trouble with all of these versions. Under Tomcat I was able
    to use it completely unmodified, well nearly so. For a
    working example see:
    
    http://sunsite.berkeley.edu:11112/kirk/servlet/xt/dynaxml/test/test
    
    What you are looking at is a single XML file being processed
    by XT using a single stylesheet. All dynamic behavior is
    implemented by passing parameters in the URL. There are no
    static files. Please excuse the speed, this is a test
    server. Also, I've been too busy to modify my stylesheets
    (both XSLT & CSS) to get it to look good in all
    browsers. Please, please, please view only with IE 5 for
    now. ;)
    
    If anyone is interested, I'd be glad to share both my
    stylesheets and server setup...
    
    khasting@library.berkeley.edu
    
    
    
     Paul Tchistopolskii  adds:
       
       PXSLServlet ( being invoked in 'simple' mode) 
       implements *exactly*  this scenario.
       
       When invoked in 'advanced' mode
       it grabs the source XML file from SQL 
       database instead of text file, but that's 
       another story.
       
       The source code is available at  www.pault.com/Pxsl/
       
       It is work in progress, but mostly that progress 
       happens in SQL part.
       
       I'l not provide too much support for version 0.2, but will 
       start providing support  for version 0.3 ( on the way ).
       
       However,  if one is able to read 2 small and clear java files - 
       the version 0.2 already has all the source code needed to suport  
       the scenario you have described above.
    

    Up to table of content


    Where can I find out about the XT extension functions?


    Mike Brown
    
    	Looking at  
                    http://www.jclark.com/xml/xt.html,  
    
    
    "Extension Functions
    
    A call to a function ns:foo where ns is bound to a namespace of the
    form http://www.jclark.com/xt/java/className is treated as a call of
    the static method foo of the class with fully-qualified name
    className."
    
    In other words, you have access to the methods of any Java class in
    the CLASSPATH known to the Java instance that's running XT. mkdir() is
    one such method that is in the standard java.io.File class.
    
    
    xt:mkdir has been mentioned on the list twice before, so none of you
    have any excuse for not having heard about xt:mkdir before now! (I'm
    kidding)
    
    
    
    In response, I received the following advice from James Clark on how to use
    what gets returned by the mkdir function in a variable:
    
    "In XT's current implementation, the definition of a result tree
    fragment valued variable is evaluated lazily once each time the
    variable is referenced. So if a definition of a result tree fragment
    valued variable has side-effects, make sure you reference that
    variable exactly once."
    
    Richard Lander gave an example.
    
    <?xml version='1.0' standalone='no'?>
    <!DOCTYPE xsl:stylesheet [
    ]>
    <xsl:stylesheet 
    	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    	xmlns:xtfile="http://www.jclark.com/xt/java/java.io.File"
    	version="1.0"
        xmlns:xt="http://www.jclark.com/xt"
        extension-element-prefixes="xt">
    
    <xsl:param name="filepath" select="'Output/'"/>
    
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match='/'>
      <xsl:comment>
        <xsl:value-of select=
    	"xtfile:mkdir(xtfile:new(string($filepath)))"/>
      </xsl:comment>
        <xsl:apply-templates/>
    </xsl:template>
    
    </xsl:stylesheet>
    
    try:
    xt mkdir.xsl mkdir.xsl
    and
    xt mkdir.xsl mkdir.xsl filepath=anydir
    
    If you are calling xt from a batch file, you may need to use quotation
    marks, as in: "filepath=anydir"
    
    
                

    Up to table of content


    How to pipeline XT processing.


    David Carlisle
    
     an alternative, for xt, is to use xt:node-set.  Run one set
     of templates and stuff the entire result tree into a
     variable then get it back as a node set and run some more
     templates on it, all within the same stylesheet.
    
                

    Up to table of content


    xt:nodeset


    David Carlisle
    
    An example of re-using parts of the output tree.
    
    
    This is a simple case, but you can get finer control if you
    want it.
    
    
    Starting from 
    
    ===========================================
    <doc xmlns="one">
    <head>test</head>
    <section>
    <head>one</head>
    <p>this paragraph
    this paragraph</p>
    <p>another paragraph
    another paragraph</p>
    </section>
    </doc>
    ==========================================
    
    You could use this stylesheet to get to html
    
    =========================================
    
    <xsl:stylesheet xmlns:xsl=
    	"http://www.w3.org/1999/XSL/Transform"
                    version="1.0"
                    xmlns:one="one"
                    xmlns:two="two"
                    >
    
    <xsl:output method="xml" indent="yes"/>
    
    <xsl:template match="one:doc">
    <two:html>
    <two:head>
      <two:title><xsl:value-of select="one:head"/></two:title>
    </two:head>
    <two:body>
      <two:h1><xsl:value-of select="one:head"/></two:h1>
    <xsl:apply-templates select="one:section"/>
    </two:body>
    </two:html>
    </xsl:template>
    
    <xsl:template match="one:section">
      <two:h2><xsl:value-of select="one:head"/></two:h2>
    <xsl:apply-templates select="*[not(self::one:head)]"/>
    </xsl:template>
    
    <xsl:template match="one:p">
      <two:p><xsl:apply-templates/></two:p>
    </xsl:template>
    
    
    </xsl:stylesheet>
    ==========================================
    
    which results in
    
    ==========================================
    <?xml version="1.0" encoding="utf-8"?>
    <two:html xmlns:one="one" xmlns:two="two">
    <two:head>
    <two:title>test</two:title>
    </two:head>
    <two:body>
    <two:h1>test</two:h1>
    <two:h2>one</two:h2>
    <two:p>this paragraph
    this paragraph</two:p>
    <two:p>another paragraph
    another paragraph</two:p>
    </two:body>
    </two:html>
    ===========================================
    
    If you had an html to text stylesheet that looked like
    
    ===========================================
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                    version="1.0"
                    xmlns:t="two"
                    >
    
    <xsl:output method="text"/>
    
    <xsl:template match="t:head">
    </xsl:template>
    
    <xsl:template match="t:h1">
    <xsl:value-of select="."/>
    <xsl:text>
    </xsl:text>
    <xsl:value-of select="translate(.,'eston','=====')"/>
    <xsl:text>
    
    </xsl:text>
    </xsl:template>
    
    <xsl:template match="t:h2">
    <xsl:value-of select="."/>
    <xsl:text>
    </xsl:text>
    <xsl:value-of select="translate(.,'eston','-----')"/>
    <xsl:text>
    </xsl:text>
    </xsl:template>
    
    <xsl:template match="t:p">
    <xsl:text>
        </xsl:text>
    <xsl:apply-templates/>
    <xsl:text>
    </xsl:text>
    </xsl:template>
    
    </xsl:stylesheet>
    ==========================================
    
    You could run that on the above output and get
    
    ==========================================
    test
    ====
    
    
    one
    - ---
    
    
        this paragraph
    this paragraph
    
    
        another paragraph
    another paragraph
    ==========================================
    
    Alternatively you could merge the two stylesheets and get
    one stylesheet that does the work of two, like this
    
    ==========================================
    <xsl:stylesheet xmlns:xsl=
    	"http://www.w3.org/1999/XSL/Transform"
                    version="1.0"
      xmlns:xt="http://www.jclark.com/xt"
      extension-element-prefixes="xt"
                    >
    
    <xsl:output method="text"/>
    
    <xsl:import href="chain2.xsl"/>
    <xsl:import href="chain1.xsl"/>
    
    
    <xsl:template match="/">
     <xsl:variable name="x">
      <xsl:apply-templates/>
     </xsl:variable>
     <xsl:apply-templates select="xt:node-set($x)/*"/>
    </xsl:template>
    
    </xsl:stylesheet>
    ==========================================
    
    which produces the above text output if given the original
    document modulo a spurious xml declaration that may or may
    not be a bug in xt (I need to check what the spec says about
    xsl:import producing multiple conflicting xsl:output )
    
                

    Up to table of content


    Multiple input to multiple output


    Robert C. Lyons
    
    
    Is it possible to use XSL to process all the XML files in a directory
    according to one stylesheet and create one output file for each input file? 
    
    Sebastian wrote
    
    surely this is best done with a conventional script? like
    
    for i in *.xml
    do
     xslprocess $i foo.xsl
    done
    
    or whatever the equivalent in Windows command language is? 
    
    David C wrote:
    
    > Can I by any chance use the document function for this? 
    only if you know in advance what the files are:
    
    <xsl:apply templates select="document('file1.xml')"/>
    <xsl:apply templates select="document('file2.xml')"/>
    .
    .
    .
    
    Which is a bit of a pain, in which case it is easier to do
    for i in *.xml ; do xt $i style.xsl ; done (whatever the nt
    command line syntax for a loop is, that is (ba)sh syntax)
    The disadvantage of that is it starts up the java virtual
    machine and reparses the stylesheet afresh on each input
    file.  This is normally what I do, but what probably I ought
    to do is instead of running xt from the command line like
    that, have a small java wrapper program that gets all the
    files in the directory and passes them to the xt class.
    
    
    Robert gives us:
    
    
    Yes, this is possible using XT.
    You can invoke XT as follows:
    
    xt source_dir stylesheet result_dir
    
    XT will apply the stylesheet to each file in the source_dir
    directory and put the output files in the result_dir
    directory.
    
    The stylesheet should not be in the source_dir. When XT
    creates an output file, it will use the same file name as
    the corresponding input file.
    
    Let's say that your input XML documents are in the IN
    directory, and your stylesheet (xlate.xsl) is in the current
    directory, and you want the output files to be placed in the
    OUT directory. Then you would execute the following command:
    
    xt in xlate.xsl out
    
    I don't think that this XT feature is documented.
    
    I found out about it last week by reading the source code of
    the com.jclark.xsl.sax.Driver class (the 19991102 version of
    XT).
    
    
    Mitch Christensen  adds
    
    I would recommend a general purpose Perl script which
    outputs an XML representation of the directory (optionally
    recursive).  This directory.xml then can be used for any/all
    file processing from within XSL.
    
    An example would be.
    
    <directory location="file:///C:/">
      <file name="foo" ext="xml" createdate="blah".../>
      ...
      <directory location="file:///C:/DOS">
      ...
      </directory>
    </directory>
    
    Once this file exists, you can use the document() function
    to process files/directories as you like.
    
    
                

    Up to table of content


    Pipe or chaining


    Mike Kay
    
    
    
    
    > Im trying to do two xslt transformations chained after each other.
    
    If you can't combine the operations directly, there are two approaches to
    chaining:
    
    1. Use the node-set extension. The first transformation creates a result
    tree fragment, you convert this to a node-set using the node-set() extension
    function, then you process this node-set with the second transformation.
    It's probably best for each transformation to use a separate mode.
    
    2. Use two stylesheets, and arrange (via the XSLT vendor's published API) to
    pipe the output of the first as the input to the second. The details will
    vary for each product. Saxon has an extension <saxon:output
    next-in-chain="phase2.xsl"> to make this kind of chaining easy.
    
    

    Up to table of content


    A site designed by Dyomedea