1. | Saxon! | |||
The first XSLT 2.0 implementation. Seems to have set the standard too? Saxonica for more information. Two versions, one which understands Schemas, one which doesn't. One paid, one open source, link to it. | ||||
2. | XSLT 2 Implementation, Oracle | |||
(July 2004. DaveP) While not yet as "reasonably complete" as Saxon, the Oracle10g XML Developer's Kit that you can download from oracle.com contains our in-progress implementation of XSLT 2.0 in it. In case you were looking to work with multiple Java, XSLT 2.0 engines. For example, I believe we've implemented the new grouping features, but not yet the ability to define functions in XSLT. Just wanted to send up a flare that other major vendors are working on XSLT 2.0 implementations, too. Michael Kay's just a little more nimble with Saxon than we've been able to be so far! :-) As we've done with XSLT 1.0, we'll ultimately offer both Java and C/C++ implementations of XSLT 2.0 as part of a future maintenance release of the Oracle XDK. Our inside-the-database XML DB functionality depends on the C implementation, for example, for XML parsing and XSLT transformation (among other things). | ||||
3. | xinclude in xslt | |||
A while ago i was searching for an implementation of xinclude in xslt 2.0, and there was no such thing. since i needed it, i did implement it and would like to make it available now. it has the following restrictions: - only xpointer barenames and the element() scheme are supported (both are required by the xinclude spec). the other xpointer schemes are not standardized anyway... - xml:base fixup will always insert absolute uris. i found this to be more practical than using relative uris. both things are allowed by the spec, if required this could be made configurable. - the content negotiation part (accept/accept-language) cannot be implemented in xslt, therefore these attributes are ignored. - since parse="text" is implemented using unparsed-text(), the exact behavior of how to determine the character encoding cannot be controlled. however, xslt's behavior has been defined to be consistent with xinclude, so everything should be fine. but if there is a problem with reading the text document, there will be an xslt error instead of an xinclude error. I have not yet done extensive testing, but some of the simpler examples of the test suites seemed to work just fine. The xslt 2.0 stylesheet is available at drnet.net and can be freely used, it is licensed under the cc lgpl (which means, if you change it, you have to make your changes openly available under the lgpl as well). | ||||
4. | Announce, XML testing tool | |||
A little utility I've been working on recently that I've called "xchecker" (I don't really like the name and I came up with it! at least its slightly better than the original of 'CheckXML'...) xchecker allows you to: - test XML (or the XML result of a transform) using XPath, XSLT, XSD, XQuery, Relax NG in combination. - embed XPath 2.0 checks (and others) in XML Schema It can be downloaded from here: http://xchecker.sf.net/ The relevant topic is to use xchecker as a test framework for XSLT. To do that you create a Check Config with a transform subject: <xchecker xmlns="http://xchecker.sf.net/";> <transform xml="xml/books.xml" xslt="xslt/books.xslt" result="result/output.html"> <check>/html/head/title = 'Books by publisher'</check> <check>exists(/html/head/meta)</check> </transform> </xchecker> xchecker will apply the transform (using Saxon) and then evaluate each <check> on the result. In order for a check to pass, xchecker looks for the following:
Any non-'true' values are returned as the failure message, so you can re-write your tests to be a little more informative in the event of a failure: <check>if (/html/head/title = 'Books by publisher') then 'true' else concat('Unexpected title:', /html/head/title)</check> ...or some other inventive use of XPath. There's more info on the xchecker home page at http://xchecker.sf.net/ | ||||
5. | xml diff | |||
With XSLT 2.0 you can define a function to give you a unique value based on the location of a node inside the document and the value should be the same if the structure is identical. Then you can use a key to match the node in the master based on that value while you walk the nodes in your document. The stylesheet below gives you a result like: <?xml version="1.0" encoding="UTF-8"?><test> <nodeA attribute1="XXX" attribute1-diff="111" attribute2="YYY" attribute2-diff="222"> <nodeA1 diff="FFF">ZZZ</nodeA1> </nodeA> <nodeA attribute1="XXX" attribute2="YYY" attribute2-diff="ZZZ"> <nodeA1>ZZZ</nodeA1> </nodeA> <nodeB>AAA</nodeB> <nodeC>BBB</nodeC> <nodeC diff="BBB">BBC</nodeC> </test> when it is applied on a document with the content <?xml version="1.0" encoding="UTF-8"?> <test> <nodeA attribute1="XXX" attribute2="YYY"> <nodeA1>ZZZ</nodeA1> </nodeA> <nodeA attribute1="XXX" attribute2="YYY"> <nodeA1>ZZZ</nodeA1> </nodeA> <nodeB>AAA</nodeB> <nodeC>BBB</nodeC> <nodeC>BBC</nodeC> </test> having a master.xml file in the same folder: <?xml version="1.0" encoding="UTF-8"?> <test> <nodeA attribute1="111" attribute2="222"> <nodeA1>FFF</nodeA1> </nodeA> <nodeA attribute1="XXX" attribute2="ZZZ"> <nodeA1>ZZZ</nodeA1> </nodeA> <nodeB>AAA</nodeB> <nodeC>BBB</nodeC> <nodeC>BBB</nodeC> </test> Here it is the stylesheet: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="2.0" xmlns:x="http://www.oxygenxml.com/xslt/functions"> <xsl:function name="x:getPath"> <xsl:param name="node"/> <xsl:value-of select=" for $i in $node/ancestor-or-self::* return concat(local-name($i), count($i/preceding-sibling::*)) "/> </xsl:function> <xsl:key name="path" match="*" use="x:getPath(.)"/> <xsl:template match="*"> <xsl:variable name="id" select="x:getPath(.)"/> <xsl:variable name="this" select="."/> <xsl:variable name="master" select="document('master.xml')/key('path', $id)"/> <xsl:copy> <xsl:if test="not($master/text()=$this/text())"> <xsl:attribute name="diff" select="$master/text()"/> </xsl:if> <xsl:for-each select="@*"> <xsl:apply-templates select="."> <xsl:with-param name="master" select="$master/@*[name()=current()/name()]"/> </xsl:apply-templates> </xsl:for-each> <xsl:apply-templates/> </xsl:copy> </xsl:template> <xsl:template match="@*"> <xsl:param name="master"/> <xsl:copy/> <xsl:if test="not(.=$master)"><xsl:attribute name="{name()}-diff" select="$master"/></xsl:if> </xsl:template> </xsl:stylesheet> Note that you can generate the diff attributes eventually in a specific namespace to avoid possible conflicts with existing attributes. | ||||
6. | EXPath, Collaboratively Defining Open Standards for Portable XPath Extensions | |||
XPath is great. Languages based on XPath, such as XQuery, XSLT and XProc, are great. The XPath recommendation provides a frame within which you can write expressions that will evaluate the same way in a lot of processors, written using plenty of different languages, in a lot of different environments, in an XML database, an in-memory processor, on a server or a client. Standard function libraries. The easiest way to provide new features to XPath is to define extension functions. We plan to provide several function libraries that each addresses a specific area. For instance performing HTTP requests, using WebDAV, reading and writing ZIP files (like EPUB eBook, Open XML and OpenDocument files,) parsing and serializing XML and HTML documents, executing XSLT transforms and XQuery queries, etc etcetera. This support for as many processor kinds as possible is great. But this is has been also a constraint to decide which feature could be included in the recommendation and which couldn't. In addition, experience harvested for several years of using XPath 2.0 pointed out missing features. This project is aimed to provide specifications for such missing features in a collaborative and implementation independent way, as well as delivering implementations of those extensions for as most processors as possible, using the mechanisms for extensibility provided by the XPath 2.0 recommendation itself. Other projects exist to define extensions for languages tightly bound to XPath, as the famous EXSLT, and the more recent EXQuery and EXProc projects. We think that those projects are really useful and fill a gap in the XML core technologies landscape. But we think also they should not reinvent their own wheels, when working at the XPath level (when that makes sense) would permit to share common work. This is just following the brilliant idea of XSLT and XQuery working groups at the W3C which joined their efforts in defining together XPath 2.0: far from competing with those projects, the idea is to promote collaboration between them. |