web analytics

Result Tree Fragment, Nodeset and msxsl:script Element

Options

codeling 1595 - 6639
@2017-09-18 09:30:31

Result tree fragments, also known as result tree fragments, are nothing more than a special type of node set. You can perform any function on them that can be performed on a node set. Or, you can also convert a result tree fragment to a node set using the node-set() function and subsequently use it any place that a node set can be used.

A result tree fragment is created as a result of using an <xsl:variable> or <xsl:param> element in a specific manner in a style sheet. The syntax for the variable and parameter elements is as follows: 

<xsl:param name=Qname select= XPath Expression >  
    template body  
</xsl:param>  

<xsl:variable name=Qname select=XPath Expression >  
    template body  
</xsl:variable>  

For the parameter element, the value is assigned to the qualified name (Qname) in several ways. You can assign a default value to the parameter by returning content from the XML Path Language (XPath) expression in the select attribute, or by assigning it the contents of the template body.

For the variable element, the value is also assigned in several ways. You can assign it by returning content from the XPath expression in the select attribute, or by assigning it the contents of the template body.

For both the parameter and variable elements, if a value is assigned by the XPath expression, then one of the four basic XPath types will be returned: Boolean, string, number, or node set. When the value is given by using a non-empty template body, then a non-XPath data type is returned, and that will be a result tree fragment.

When a variable is bound to a result tree fragment instead of one of the four basic XPath data types, this is the only time that an XPath query returns a type that is not one of the four XPath object types. Result tree fragments and their behavior are discussed in the World Wide Web Consortium (W3C) specification at www.w3.org/XSLT, section 11.1 Result Tree Fragments through section 11.6 Passing Parameters to Templates. Also, section 1 Introduction discusses how templates can contain elements from the XSLT namespace that return or create result tree fragments.

A result tree fragment, in concept, behaves like a node set with nothing more than a single root node. However, the rest of the nodes returned are child nodes. To programmatically see the child nodes, copy the result tree fragment to the result tree using the <xsl:copy-of> element. When the copy-of is performed, all the child nodes are also copied to the result tree in sequence. Until a copy or copy-of is used, a result tree fragment is not part of the result tree or the output from the transformation.

To iterate over the returned nodes of a result tree fragment, an XPathNavigator is used. The following code sample shows how to create a result tree fragment within a style sheet by calling the function with a parameter fragment, which contains XML.

 

Here is a sample showing a variable, which is in Rich Text Format (RTF), and hence, a type of result tree fragment, that is not converted to a node set. Instead, it is passed to a script function, and the XPathNavigator is used to navigate over the nodes.

<xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"  
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"  
        xmlns:user="urn:books"  
        exclude-result-prefixes="msxsl">  

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>  

<xsl:variable name="node-fragment">  
    <book>Book1</book>  
    <book>Book2</book>  
    <book>Book3</book>  
    <book>Book4</book>  
</xsl:variable>  

<msxsl:script implements-prefix="user" language="c#">  

<![CDATA[  
    public string func(XPathNavigator nav)  
    {  
        bool b = nav.MoveToFirstChild();  
        if (b)  
            return nav.Value;  
        else  
            return "Does not exist";  
    }  

]]>  

</msxsl:script>  

<xsl:template match="/">  
    <first_book>  
        <xsl:value-of select="user:func($node-fragment)"/>  
    </first_book>  
</xsl:template>  

</xsl:stylesheet>  

The result of transforming any XML with this style sheet is shown in the following output.

<first_book xmlns:user="urn:books">Book1</first_book>  

As stated above, the node-set function enables you to convert a result tree fragment into a node set. The resulting node always contains a single node that is the root node of the tree. If you convert a result tree fragment to a node set, then you can use it anywhere a regular node set is used, such as in a for-each statement or in the value of a select attribute. The following lines of code show the fragment being converted to a node set and used as a node set:

<xsl:for-each select="msxsl:node-set($node-fragment)">

<xsl:value-of select="user:func(msxsl:node-set($node-fragment))"/>

When a fragment is converted to a node set, you no longer use the XPathNavigator to navigate over it. For a node set, you use the XPathNodeIterator instead. +

In the following example, $var is a variable that is a node tree in the style sheet. The for-each statement, combined with the node-set function, allows the user to iterate over this tree as a node set. 

<xsl:stylesheet xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"  
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"  
                xmlns:user="http://www.adventure-works.com"  
                version="1.0">  
    <xsl:variable name="states">  
        <node1>AL</node1>  
        <node1>CA</node1>  
        <node1>CO</node1>  
        <node1>WA</node1>  
    </xsl:variable>  

    <xsl:template match="/">  
            <xsl:for-each select="msxsl:node-set($states)"/>   
    </xsl:template>  
</xsl:stylesheet>  

Here is another example of a variable that is in RTF, and hence of type result tree fragment, that is converted to a node set before being passed to a script function as XPathNodeIterator. 

<xsl:stylesheet version="1.0" xmlns:xsl= "http://www.w3.org/1999/XSL/Transform"  
        xmlns:msxsl="urn:schemas-microsoft-com:xslt"  
        xmlns:user="urn:books"  
        exclude-result-prefixes="msxsl">  

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>  

<xsl:variable name="node-fragment">  
    <book>Book1</book>  
    <book>Book2</book>  
    <book>Book3</book>  
    <book>Book4</book>  
</xsl:variable>  

<msxsl:script implements-prefix="user" language="c#">  

<![CDATA[  
    public string func(XPathNodeIterator it)  
    {  
        it.MoveNext();   
        return it.Current.Value;   
        //it.Current returns XPathNavigator positioned on the current node  
    }  

]]>  

</msxsl:script>  
<xsl:template match="/">  
    <books>  
        <xsl:value-of select="user:func(msxsl:node-set($node-fragment))"/>  
    </books>  
</xsl:template>  

</xsl:stylesheet>  

The following is the result of transforming XML with this style sheet: 

<books xmlns:user="urn:books"> Book1Book2Book3Book4</books>  
@2017-09-18 13:24:15

msxsl:script Element Definition

The msxsl:script element is a Microsoft extension to the XSLT 1.0 recommendation and has the following definition: + 

<msxsl:script language = "language-name" implements-prefix = "prefix of user namespace"> </msxsl:script>  

The msxsl prefix is bound to the urn:schemas-microsoft-com:xslt namespace URI. The style sheet must include the xmlns:msxsl=urn:schemas-microsoft-com:xslt namespace declaration.

The language attribute is optional. Its value is the code language of the embedded code block. The language is mapped to the appropriate CodeDOM compiler using the CodeDomProvider.CreateProvider method. The XslCompiledTransform class can support any Microsoft .NET language, assuming the appropriate provider is installed on the machine and is registered in the system.codedom section of the machine.config file. If a language attribute is not specified, the language defaults to JScript. The language name is not case-sensitive so 'JavaScript' and 'javascript' are equivalent. +

The implements-prefix attribute is mandatory. This attribute is used to declare a namespace and associate it with the script block. The value of this attribute is the prefix that represents the namespace. This prefix can be defined somewhere in a style sheet.

@2017-09-18 13:25:27

Script Functions

Functions can be declared within the msxsl:script element. When a function is declared, it is contained in a script block. Style sheets can contain multiple script blocks, each operating independent of the other. That means that if you are executing inside a script block, you cannot call a function that you defined in another script block unless it is declared to have the same namespace and the same scripting language. Because each script block can be in its own language, and the block is parsed according to the grammar rules of that language parser we recommend that you use the correct syntax for the language in use. For example, if you are in a Microsoft C# script block, use the C# comment syntax. 

The supplied arguments and return values to the function can be of any type. Because the W3C XPath types are a subset of the common language runtime (CLR) types, type conversion takes place on types that are not considered to be an XPath type. The following table shows the corresponding W3C types and the equivalent CLR type.

W3C type CLR type
String String
Boolean Boolean
Number Double
Result Tree Fragment XPathNavigator
Node Set XPathNodeIterator

CLR numeric types are converted to Double. The DateTime type is converted to String. IXPathNavigable types are converted to XPathNavigator. XPathNavigator[] is converted to XPathNodeIterator.

All other types throw an error.

@2017-09-18 13:29:32

Importing Namespaces and Assemblies

The XslCompiledTransform class predefines a set of assemblies and namespaces that are supported by default by the msxsl:script element. However, you can use classes and members belonging to a namespace that is not on the predefined list by importing the assembly and namespace in msxsl:script block.

Assemblies

The following two assemblies are referenced by default: 

  • System.dll

  • System.Xml.dll

  • Microsoft.VisualBasic.dll (when the script language is VB)

You can import the additional assemblies using the msxsl:assembly element. This includes the assembly when the style sheet is compiled. The msxsl:assembly element has the following definition: 

<msxsl:script>  
  <msxsl:assembly name="system.assemblyName" />  
  <msxsl:assembly href="path-name" />  
    <![CDATA[  
    // User code  
    ]]>  
</msxsl:script>  

The name attribute contains the name of the assembly and the href attribute contains the path to the assembly. The assembly name can be a full name, such as "System.Data, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", or a short name, such as "System.Web".

Namespaces

The following namespaces are included by default: +

  • System

  • System.Collection

  • System.Text

  • System.Text.RegularExpressions

  • System.Xml

  • System.Xml.Xsl

  • System.Xml.XPath

  • Microsoft.VisualBasic (when the script language is VB)

You can add support for additional namespaces using the namespace attribute. The attribute value is the name of the namespace.

<msxsl:script>  
  <msxsl:using namespace="system.namespaceName" />  
    <![CDATA[  
    // User code  
    ]]>  
</msxsl:script>  

Comments

You must Sign In to comment on this topic.


© 2024 Digcode.com