Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 76 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
76
Dung lượng
172,46 KB
Nội dung
Chapter 12. Extending and Embedding XSLT I think everybody should have a great Wonderbra. There's so many ways to enhance them, everybody does it. —Christina Aguilera Truly ambitious programmers are never satisfied with what they are given and are obsessively driven to enhance what they have. I say "ambitious" rather than "great" because greatness, in my opinion, comes from knowing when it is wiser to work within the system versus when it is best to extend the system. Nevertheless, this chapter is dedicated to extending the system both from the perspective of XSLT needing functionality best implemented in another language and from the perspective of other languages needing XSLT. Extending XSLT is, by definition, a facility on the fringes of the specification. Extensions decrease the portability of the XSLT script. This is definitely a hazard when you use extensions provided natively by your XSLT processor or when implementing your own extension. It is true even if you implement your extensions in a highly portable language like Java. The most obvious reason is that some XSLT processors are not written in Java and are thus unlikely ever to support Java-based extensions. However, even if you only want your extensions to work in Java-based XSLT processors, you might still find that the extension mechanism of XSLT was not fully standardized in Version 1.0. This state of affairs improved in Version 1.1, but 1.1 is no longer an official XSLT release and many processors do not support it. Surprisingly, XSLT 2.0 does not promise any standardization with respect to extensions. Extensibility in XSLT 2.0 The current XSLT 2.0 Working Draft (http://www.w3.org/TR/xslt20/) has this to say about extensions: This specification does not define any mechanism for creating or binding implementations of extension instructions or extension functions, and does not require that implementations support any such mechanism. Such mechanisms, if they exist, are implementation-defined. Therefore, an XSLT stylesheet that must be portable between XSLT implementations cannot rely on particular extensions being available. XSLT provides mechanisms that allow an XSLT stylesheet to determine whether the implementation makes particular extensions available, and to specify what should happen if those extensions are not available. If an XSLT stylesheet is careful to make use of these mechanisms, it is possible for it to take advantage of extensions and still retain portability. This statement is unfortunate because although it does not make it impossible to write portable extensions with stylesheets, it makes it difficult enough that many developers will be forced to use one XSLT implementation. EXSLT.org is a portal dedicated to establishing standards XSLT implementers can follow when implementing common extensions. Chapter 2 and Chapter 3 mentioned EXSLT with respect to math extensions and date extensions. EXSLT.org also organized other extension categories, some of which this chapter touches upon. It is certainly a site worth visiting before going off and implementing your own extension. There is a good chance that someone either developed such an extension or put some thought into how the extension should work. In contrast to extending XSLT, embedding XSLT involves invoking XSLT transformations from another language without forking your XSLT processor in a separate process. You will see how XSLT can be accessed from within Java- and Perl-based programs. When writing this chapter, it quickly became apparent that you could easily dedicate a whole book to extension and embedding—especially when you consider the cross between implementations, extension languages, and interesting examples. To keep this chapter manageable, I compromised by alternating between Xalan Java 2 and Saxon and sticking mostly to Java and JavaScript. This chapter also discusses MSXML. To prevent repetition, this section explains how to use extensions in both Saxon and Xalan Java 2. 12.1 Saxon Extension Functions Saxon lets you access extension junctions written in Java by using the interface defined in the XSLT 1.1 draft standard. Although this feature was dropped from XSLT 2.0, it will probably remain in Saxon since vendors can do what they please on the 2.0 standard's extensibility front. However, the element's namespace could be changed. Java is the only extension language currently supported by Saxon, so extension function bindings are defined along the lines of the following example: <xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:Math="java:java.lang.Math" exclude-result-prefixes="Math"> <xsl:script implements-prefix="Math" xmlns:Math="java:java.lang.Math" language="java" Here the naming convention used for the namespace is not strictly required. However, if followed, it makes the xsl:script element optional. Hence, if you need to access an extension only once, you can write something like: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:variable name="PI" select="4 * Math:atan(1.0)" xmlns:Math="java:java.lang.Math"/> <! > </xsl:stylesheet> Here the namespace encodes the binding to the Java implementation rather than the xsl:script. Note that these binding techniques are independent; if you use the xsl:script element, then the namespace's content does not matter. On the other hand, if you omit the xsl:script, the namespace has the sole responsibility of binding the Java implementation. 12.2 Saxon Extension Elements Extension elements in Saxon can be implemented only in Java. You must define a namespace that binds the extension to its implementation. However, the rules are more explicit here than with extension functions. The namespace must end in a /, followed by the fully qualified class name of a Java class that implements the interface com.icl.saxon.ExtensionElementFactory: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:acmeX="http://www.acmeX.com/com.acemX.SuperExtensionFa ctory" extension-element-prefixes="acmeX"> <! > </xsl:stylesheet> The prefix must also be listed in the stylesheet's extension-element-prefixes attribute. Details of the ExtensionElementFactory are covered in Recipe 12.15. 12.3 Xalan Java 2 Extension Functions Extension functions in Xalan Java 2 are bound using two Xalan extensions, xalan:component and xalan:script, where the relevant Xalan namespace URI is http://xml.apache.org/xslt. The xalan:component element associates the extension namespace prefix with the names of extension functions or elements that will be defined by the enclosing xalan:script element. The xalan:script element defines the language used to implement the extension and its associated implementation. The choices here vary. Casual users of Java-based extensions should note that Xalan supports an abbreviated syntax that does not require the use of the xalan:component or xalan:script elements. Simply declare the namespace in one of the forms shown here, and invoke the Java function using the appropriate syntax. For scripting languages, this shortcut does not apply. 12.4 Java Extension Function Using the Class Format Namespace <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt" xmlns:Math="xalan://java.lang.Math"> <xalan:component prefix="Math" functions="sin cos tan atan"> <xalan:script lang="javaclass" </xalan:component> <xsl:variable name="PI" select="4.0 *"/> If you use this form and omit the xalan:component element, then your stylesheet can work with both Saxon and Xalan. 12.5 Java Extension Function Using the Package Format Namespace <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt" xmlns:myJava="xalan://java.lang"> <xalan:component prefix="Math" functions="sin cos tan atan"> <xalan:script lang="javaclass" </xalan:component> <xsl:variable name="PI" select="4.0 * myJava:Math.atan(1.0)"/> <! > </xsl:stylesheet> This form is useful if you want to reference many classes within the same package. 12.6 Java Extension Function Using the Java Format Namespace <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt" xmlns:java="http://xml.apache.org/xslt/java"> <xalan:component prefix="Math" functions="sin cos tan atan"> <xalan:script lang="javaclass" </xalan:component> <xsl:variable name="PI" select="4.0 * java:java.lang.Math:atan(1.0)"/> <! > </xsl:stylesheet> Use this form if you want to access a wide variety of Java-based extensions with a single namespace declaration. The disadvantage is that each invocation becomes more verbose. 12.7 Scripting Extension Function Using Inline Script Code <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xalan="http://xml.apache.org/xslt" xmlns:trig="http://www.acmeX.com/extend/trig"> <xalan:component prefix="trig" functions="sin cons tan atan"> <xalan:script lang="javascript"> function sin (arg){ return Math.sin(arg);} function cos (arg){ return Math.cos(arg);} function tan (arg){ return Math.tan(arg);} function atan (arg){ return Math.atan(arg);} </xalan:script> </xalan:component> <xsl:variable name="PI" select="4.0 * trig:atan(1.0)"/> <! > </xsl:stylesheet> Saxon currently supports JavaScript, NetRexx, BML, JPython, Jacl, JScript, VBScript, and PerlScript, but appropriate extensions need to be obtained from third parties supporting the respective languages. See http://xml.apache.org/xalan-j/extensions.html#supported-lang for details. 12.8 Xalan Java 2 Extension Elements Extension elements in Xalan can be written in Java or in a supported scripting language. Java- based extensions elements also allow the shortcut syntax that dispenses with the xalan:component or xalan:script elements. [...]... you might consider using an EXSLT extension called func:function that is implemented by Saxon and the latest version of Xalan (Version 2.3.2) The following code is a template from Chapter 2 reimplemented as a function: ... Extension Functions Microsoft's MSXML 3.0, 4.0, and NET XSLT processor is extensible via Jscript and VBScript MSXML NET adds C# extensibility Extensions in MSXML are specified using the ms:script element: ... you can access JavaScript's regular expression library: ... strings, structure, or as a simple looping construct: ... an XSLT solution faster or more simply than you could if you constrained yourself to standard XSLT In a few cases, they allow you to do things that are impossible with standard XSLT On the other hand, they can lock you into an implementation whose future is uncertain EXSLT.org encourages implementers to adopt uniform conventions for the most popular extensions, so you should certainly prefer an EXSLT... Imagine that a stylesheet called strip .xslt stripped out specific elements from an XML document representing a book, and a stylesheet called contents .xslt created a table of contents based on the hierarchical structure of the document's markup You could create a pipeline between the stylesheets as follows: With JavaScript, you can actually implement functions that have side effects and objects that maintain state:[1] [1] Shame on me for suggesting such a thing! Seriously, though, when you leave the confines of XSLT, you need not play by its rules, but you must accept the consequences ...12 .9 Java Extension Element extension-element-prefixes="MyExt"> . contrast to extending XSLT, embedding XSLT involves invoking XSLT transformations from another language without forking your XSLT processor in a separate process. You will see how XSLT can be accessed. <xsl:stylesheet xmlns:xsl="http://www.w3.org/ 199 9/XSL/Transform" xmlns:xalan="http://xml.apache.org /xslt& quot; xmlns:java="http://xml.apache.org /xslt/ java"> <xalan:component. elements. 12 .9 Java Extension Element <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/ 199 9/XSL/Transform" xmlns:xalan="http://xml.apache.org /xslt& quot;