US
FAQ 4xt
FAQ 4xt [ 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 > 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 í.
For example,
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Tranform"
version="1.0">
<xsl:output method="html">
<xsl:template match="/">
<html>í</html>
</xsl:template>
</xsl:stylesheet>
outputs:
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>í</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><!ENTITY </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> "&#</xsl:text>
<xsl:if test="60 = ../@dec or 38 = ../@dec">
<xsl:text>38;#</xsl:text>
</xsl:if>
<xsl:value-of select="../@dec"/>
<xsl:text>;" ><!--</xsl:text>
<xsl:value-of select="../@id"/>
<xsl:text> </xsl:text>
<xsl:value-of select="desc"/>
<xsl:text> -->
</xsl:text>
</xsl:for-each>
</xt:document>
</xsl:template>
<xsl:template name="pad">
<xsl:param name="x"/>
<xsl:if test="$x > 0">
<xsl:text> </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 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  , you get C2 A0 - a UTF-8
representation of  
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>
i G I ć
</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 ć
, but I when I try to output it as xml by changing the method to
"xml", I get:
i G I Ä ?
and I'd like to get in my xml output:
i G I ć
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 ć 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 ÿ (and equivalently
ÿ) _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
ć or ý
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
k (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 Mac Viewing 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.