<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet href="../../make-menu.xsl" type="text/xsl"?><html>
   <head>
      <this-is section="extensibility" page="dotnetextensions" subpage="staticmethods.net"/>
      <!--
           Generated at 2010-10-29T18:20:48.427+01:00--><title>Saxonica: XSLT and XQuery Processing: Calling Static Methods in a .NET Class</title>
      <meta name="coverage" content="Worldwide"/>
      <meta name="copyright" content="Copyright Saxonica Ltd"/>
      <meta name="title"
            content="Saxonica: XSLT and XQuery Processing: Calling Static Methods in a .NET Class"/>
      <meta name="robots" content="noindex,nofollow"/>
      <link rel="stylesheet" href="../../saxondocs.css" type="text/css"/>
   </head>
   <body class="main">
      <h1>Calling Static Methods in a .NET Class</h1>
      <p><b>Static methods</b> can be called directly.
The localname of the function must match the name of a public static method in this class. The names
 match if they contain the same characters, excluding hyphens and forcing any character that follows
 a hyphen to upper-case. For example the XPath function call <code>To-string()</code> matches the .NET method
 <code>ToString()</code>; but the function call can also be written as <code>ToString()</code> if you prefer.</p>
      <p>If there are several methods in the class that match the localname, and that have the correct number
 of arguments, then the system attempts
 to find the one that is the best fit to the types of the supplied arguments: for example if the 
 call is <code>f(1,2)</code> then a method with two <code>int</code> arguments will be preferred
  to one with two <code>float</code>
 arguments. The rules for deciding between methods are quite complex. Essentially, for each candidate method,
 Saxon calculates the "distance" between the types of the supplied arguments and the .NET class of the 
 corresponding argument in the method's
 signature, using a set of tables given below. For example, the distance between the XPath data type <code>xs:integer</code>
  and the .NET type <code>long</code> is very small, while the distance between an XPath <code>xs:integer</code> and a 
  .NET <code>bool</code>
 is much larger. If there is one candidate method where the distances of all arguments are less-than-or-equal-to
 the distances computed for other candidate methods, and the distance of at least one argument is smaller,
 then that method is chosen.</p>
      <p>If there are several methods with the same name and the correct number of arguments, but none is
 preferable to the others under these rules, an error is reported: the message indicates that there is
 more than one method that matches the function call.</p>
      <p>This binding is carried out statically, using the static types of the supplied arguments, not the dynamic
 types obtained when the arguments are evaluated. If there is insufficient static type information to distinguish
 the candidate methods, an error is reported. You can supply additional type information using the <code>treat as</code>
 expression, or by casting. Often it is enough simply to declare the types of the variables used as arguments to the function call.</p>
      <p>For example (in XSLT):</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;xsl:value-of select="math:Sqrt($arg)" xmlns:math="clitype:System.Math"/&gt;
</code>
         </pre>
      </div>
      <p>This will invoke the static method <code>System.Math#Sqrt()</code>, applying it to the value of the variable
<code>$arg</code>, and copying the value of the square root of <code>$arg</code> to the result tree.
The value of $arg must be convertible to a double under the same rules as for a native XPath function call.</p>
      <p>Similarly (in XQuery):</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;a xmlns:double="type:System.Double"/&gt; 
                              {double:MaxValue()} &lt;/a&gt;
</code>
         </pre>
      </div>
      <p>This will output the value of the static field <code>System.Double#MaxValue</code>. (In practice, it
is better to declare the namespace in the query prolog, or predeclare it using the API, because it will then not 
be copied to the result tree.)</p>
      <p>A static method called as an extension function may have an extra first argument of
 type <a class="bodylink" href="../../javadoc/net/sf/saxon/expr/XPathContext.html"><code>net.sf.saxon.expr.XPathContext</code></a>.
This argument is not
supplied by the calling XPath or XQuery code, but by Saxon itself. 
The <code>XPathContext</code> object provides methods to access many
internal Saxon resources, the most useful being <code>getContextItem()</code> which returns the context item
from the dynamic context. The class <code>net.sf.saxon.expr.XPathContext</code> is in the assembly
<code>saxon9.dll</code>, and the module containing the code of the extension function will therefore need to contain a reference
to that DLL. The class itself is written in Java, and is documented in the Javadoc documentation. 
The <code>XPathContext</code> object is available with static or instance-level methods, but
not with constructors.</p>
      <p>The following example shows a function that obtains the host language from the Saxon evaluation context:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>        public static string HostLanguage(net.sf.saxon.expr.XPathContext context)
        {
            int lang = context.getController().getExecutable().getHostLanguage();
            if (lang == net.sf.saxon.Configuration.XQUERY)
            {
                return "XQuery";
            }
            else if (lang == net.sf.saxon.Configuration.XSLT)
            {
                return "XSLT";
            }
            else if (lang == net.sf.saxon.Configuration.XPATH)
            {
                return "XPath";
            }
            else
            {
                return "unknown";
            }
        }</code>
         </pre>
      </div>
      <p>If this method appears in class <code>com.example.code.Utils</code>, then it can be accessed
using the following code in XSLT:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;xsl:value-of select="nd:HostLanguage()" 
    xmlns:nd="java:com.example.code.Utils"/&gt;</code>
         </pre>
      </div>
      <p>or the following in XQuery:</p>
      <div class="codeblock"
           style="border: solid thin; background-color: #B1CCC7; padding: 2px">
         <pre>
            <code>&lt;line xmlns:nd="java:com.example.code.Utils"&gt;
    { nd:HostLanguage() }
&lt;/line&gt;</code>
         </pre>
      </div>
      <table width="100%">
         <tr>
            <td>
               <p align="right"><a class="nav" href="constructors.net.xml">Next</a></p>
            </td>
         </tr>
      </table>
   </body>
</html>