Why extend the XSLT style sheet function?
The XML-based Extensible style sheet language XSL and its conversion XSLT implement the conversion of XML source files from one format to another. By defining a series of rules-compliant templates in the XSL file, the XML document that matches these templates can be converted to HTML page files that can be displayed, XML files that meet other needs, or files with other structures. When this is done in the XSLT document, there is no obvious process control or traditional programming sense.Algorithm, Or even noProgramCodeAndProgramming Language. Most of the time, this can well complete the task.
No language can be absolutely perfect, and XSL is only a markup language. It alone cannot complete all tasks. Just as without XPath and XSLT, XML can only be a set of tags at best, and nothing can be done. In particular, if we need not only to change the display mode or structure of a document, but also to make more control over the document, simply expose the limitations of using XSLT. For example, you can obtain user-typed parameters to control the conversion output, connect to external data sources, and reference certain computing results, simply using a descriptive language like XSLT cannot provide satisfactory solutions. As we know, the program code can easily solve these problems.
Use embedded scripts to extend the XSLT style sheet Function
XML is easy to expand, which is one of the reasons it can be widely accepted in a short time. XSLT is fully implemented based on XML and should be easy to expand. Indeed, W3C recommendation standard XSLT provides specialized extensions for different processors/parsers. Basically, different processors/parsers can use extended functions in XPath expressions, XSLT template body content, or top-level elements. In addition, like functions/methods in any programming language, these extended functions can be used to complete the required sub-functions. They can also be "defined at a time and called multiple times ". More importantly, these embedded scripting functions can be called not only in XSLT markup language, but also in advanced languages. The group function provided by the scripting language is richer than that provided by pure XSLT. It is often used to perform more complex operations on the document content (such as scientific computing of its application or access to external information sources ), this feature greatly extends the XSLT function.
During implementation, you must specify the created extension functions in a specified namespace and provide implementation in a specific XSLT processor. The reason why namespaces must be used is that namespaces not only prevent conflicts between XSLT names from different sources. More importantly, it also identifies extensions so that other processors can ignore the implementations specific to specific processors and rely on this namespace to reference extension functions in other parts of XSLT.
Msxml xslt Processor <Msxsl: SCRIPT> implements and extends the functions of the element and its attributes implements-prefix to provide script-level support. The naming space specified by Microsoft allows the msxml xslt processor to locate script code in the style sheet. The language attribute of the <msxsl: SCRIPT> element tells the interpreter used by the runtime script, and the implements-Prefix attribute value is the prefix of the extended function, which is declared elsewhere in the XSLT document. Once these attributes are defined, the XSLT processor can use this information to call the interpreter runtime script (such as the C # compiler) and <Msxsl: SCRIPT> code for implementing extended functions in the element. In other aspects of the style sheet <XSL: value-of> the template provided by the element is associated with the extension function through the seletct attribute. For example, the extension function calculation result is executed and output.
<Msxsl: SCRIPT> the element is defined as follows:
<Msxsl: script language = "language-name" implements-Prefix = "prefix of user's namespace"> </msxsl: SCRIPT> |
Where:
The language attribute indicates the language option. It is similar to the language attribute of the script element on the HTML page. Its value provides the script language used for function/method definition. However, the language attribute is not mandatory, but if it is specified, its value must be one of the following languages: C #, VB, JScript, JavaScript, VisualBasic, or CSHARP. If not specified, the default language is JScript. Different from other XSLT elements and attributes, the language names are case-insensitive. Therefore, "JavaScript" and "JavaScript" are equivalent.
The implements-Prefix attribute is mandatory. It is used to specify the namespace prefix and associate it with the script block. The attribute value indicates the namespace prefix. The namespace represented by the prefix must be defined at a certain position in the style sheet.
Like any other XML Element tag, <Msxsl: SCRIPT> "msxsl" in the element indicates the namespace prefix. However, the name "msxsl" is not important, that is, it is not necessarily "msxsl". You can name it another string, for example:
Xmlns: myxsl = "urn: Schemas-Microsoft-com: XSLT" xmlns: myns = "urn: Schemas-Microsoft-com: XSLT" |
In this way, the namespace prefix is changed to "myxsl" or "myns". Accordingly, the elements <Msxsl: SCRIPT> is changed <Myxsl: SCRIPT> or <myns: SCRIPT>. This change will not affect the results, if you are consistent across all parts of your XSLT document. (In this article, all <SCRIPT> msxsl is used in the element to be consistent with Microsoft's default settings)
I wonder whether you have noticed that in the above statement, no matter how the namespace prefix changes, its value is always urn: Schemas-Microsoft-com: XSLT. This is required. To correctly extend the XSLT style sheet function, you must specify this namespace. Namespace: urn: Schemas-Microsoft-com: XSLT complies with W3C recommendation standards and is supported in Microsoft msxml3.0 and later processors. It not only supports embedded script programming in XSLT, but also supports other extension functions. For example, use the node-set () function in XSL.
Generally <XSL: stylesheet> defines the <msxsl: SCRIPT> element in the element, and then defines the extension function in the <msxsl: SCRIPT> element. You can also The COM object is instantiated in <msxsl: SCRIPT>, which greatly expands the pure XSLT function. (However, your security settings may prevent your script from instantiating client objects)
Extended functions are included in <Msmsl: SCRIPT> the script block defined by the element. A style sheet can contain multiple script blocks. The operations of each script block are independent of each other. That is to say, if the script block is executed internally, the function defined in other script blocks cannot be called unless the script block is declared to have the same namespace and the same script language. Since each script block can use its own language, the analysis of the script block will follow the syntax rules of the Language Analyzer. The syntax used must be correct for the language used. For example, if the C # script block is used, the XML annotation node is used in the block. <! -- An XML comment --> is incorrect. You should use the C # annotator "//" or "/*... */".
The following example creates a script block with the namespace prefix "mycompany". The script contains a "sum" function, which accepts two double parameters and calculates their sum, then convert it into string output. Later, the XSL Element The select attribute of <XSL: value-of> calls this function and outputs the result.
private string sum (double A, double B) {return (A + B ). tostring () ;}
|
To demonstrate the effect <XSL: value-of select = "mycompany: sum (5.0)"/> when calling the extension function Sum, two double values 10.0 and are hard encoded. In reality, the parameter value should be from the XML source document or passed in through custom parameters.
Given the special requirements of XML element content, that is, it cannot directly contain ", ', <,>, &, and all non-display characters, operators, identifiers, or delimiters in a given language may exactly contain these characters, which may be incorrectly interpreted as XML. Replacing all these characters with the corresponding entity (Standard entity and character entity) references will reduce the readability of the XML file. Therefore, when using the msxsl: script element, we strongly recommend that you place the script in CDATA regardless of the language used. For example, the following XML shows the CDATA section template for placing code.
<Msxsl: script implements-Prefix = 'myscript' Language = 'C # '> <! [CDATA [<! -- Place the code here -->]> </msxsl: SCRIPT> |
For example, the following example shows how to use the logical and operator in a script.
<Msxsl: script implements-Prefix = 'myscript' Language = 'C # '> Public String book (string ABC, string XYZ) {If (ABC = ABC) & (ABC = xyz) return BAR + XYZ; else return NULL ;}</msxsl: SCRIPT> |
Because the "&" character is not escaped, this will cause an exception. Load documents as XML without any special processing for text between msxsl: script element tags.
. Net using XSLT style sheets with extended functions
The XSLT conversion object in. NET provides support for embedding script language with Script extension elements in the XSLT document. The terratransform class provides specific implementation for this purpose. It contains methods that use XSLT style sheets to convert XML data to the specified output. Xsltransform used to load the XSLT conversion document .. the load () method accepts the style sheet containing the embedded script and implements the transform. the Transform () method uses this style sheet to convert the XML source document to the specified output. Whether or not the source XSL document contains embedded scripts does not affect the compilation of program code. You do not need to add additional code. That is to say, when writing program code in advanced languages, the XSL document containing the embedded script uses the same conversion statement as the XSL document without the embedded script.
Supported by the xsltransform class <Msxsl: SCRIPT> embedded script for the element. When a style sheet is loaded, any defined functions are packaged into Microsoft intermediate language (msil) in the class definition, so there is no performance loss.
Based on the above knowledge, Visual Studio is used below.. Net SDK creates a console application use‑tscript, which calls the trans that contain the embedded script. XSL conversion document, for data. the XML source document executes the conversion and outputs the result to a new newxml. XML file. In this example, the XSLT embedding script is used to calculate the area of a triangle when the bottom side of the triangle is known and the height of the triangle corresponds to the edge.
Using system; using system. XML; using system. XML. XSL; using system. io; namespace mycompanyuri. usexsltscript {class XSLT {private const string xmlfile = ".. /.. /data. XML "; // XML source document private const string character file = ".. /.. /Trans. XSL "; // XSL conversion document private const string newxml = ".. /.. /outxml. XML "; // converted XML file public static void main () {xmldocument Doc = new xmldocument (); // instantiate the XML Document Object Doc. load (xmlfile); // load the XML document transform XSLT = new transform (); // instantiate the transform ttransform object XSLT. load (transform file); // load the XSLT conversion style table filestream mystream = new filestream (newxml, filemode. openorcreate); // open the file xmltextwriter writer = new xmltextwriter (mystream, null) as a stream; // instantiate the XML writer and provide writer output on the console. formatting = formatting. indented; // sets the indent format of the output. transform (Doc, null, writer); // convert the XML file and output the writer. close ();}}} |
XML source file data. xml:
<? XML version = "1.0" encoding = "UTF-8"?> <Triangles> <triangle> <size> <width> 2 </width> |
Trans. XSL file:
<? XML version = "1.0" encoding = "UTF-8"?> <XSL: stylesheet version = "1.0" xmlns: XSL = "http://www.w3.org/1999/XSL/Transform" xmlns: msxsl = "urn: Schemas-Microsoft-com: XSLT" xmlns: myscript = "urn: myns "> <msxsl: script language =" C # "implements-Prefix =" myscript "> <! [CDATA [Public double trianglearea (double width, double height) {double area = width * Height/2; // area formula: (bottom * Height)/2 return area; // return Triangle Area}]> </msxsl: SCRIPT> <XSL: template match = "// triangles"> <triangles> <XSL: for-each select = "Triangle/size"> <! -- Select the size node --> <triangle> <XSL: copy-of select = ".../size"/> <! -- Copy the size node --> <area> <XSL: value-of select = "myscript: trianglearea (width, height)"/> <! -- Call the function --> </area> </Triangle> </XSL: For-each> </triangles> </XSL: Template> </XSL: stylesheet> |
Execute this console program and generate the outxml. xml file in the application directory. It will contain the bottom side, height, and area of the given triangle.
In addition, when running this application, you can obviously feel that the program has a short delay. This is because it takes about 2 seconds to load the C # compiler and run the Embedded C # script before loading the style sheet to process embedded scripts.
It should be noted that the parameters and return values of extension functions embedded in XSLT scripts must be one of W3C XPath types, which are not the same. the types supported by. NET are exactly the same (about these W3C XPath types and. for information about the net type, see msdn ). If the script function uses another type, or if the function is not compiled when it is loaded into the external transform object, an exception is thrown.