| <HTML><HEAD><SCRIPT language="JavaScript" src="resources/script.js" type="text/javascript"></SCRIPT><TITLE>Xalan-C++ Extension Functions</TITLE></HEAD><BODY alink="#ff0000" bgcolor="#ffffff" leftmargin="4" link="#0000ff" marginheight="4" marginwidth="4" text="#000000" topmargin="4" vlink="#0000aa"><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD align="left" height="60" rowspan="3" valign="top" width="135"><IMG alt="logo" border="0" height="60" hspace="0" src="resources/logo.gif" vspace="0" width="135"></TD><TD align="left" colspan="4" height="5" valign="top" width="456"><IMG alt="line" border="0" height="5" hspace="0" src="resources/line.gif" vspace="0" width="456"></TD><TD align="left" height="60" rowspan="3" valign="top" width="29"><IMG alt="right" border="0" height="60" hspace="0" src="resources/right.gif" vspace="0" width="29"></TD></TR><TR><TD align="left" bgcolor="#0086b2" colspan="4" height="35" valign="top" width="456"><IMG alt="" border="0" height="35" hspace="0" src="graphics/extensions-header.jpg" vspace="0" width="456"></TD></TR><TR><TD align="left" height="20" valign="top" width="168"><IMG alt="bottom" border="0" height="20" hspace="0" src="resources/bottom.gif" vspace="0" width="168"></TD><TD align="left" height="20" valign="top" width="96"><A href="http://xalan.apache.org/" onMouseOut="rolloverOff('xml');" onMouseOver="rolloverOn('xml');" target="new"><IMG alt="http://xalan.apache.org/" border="0" height="20" hspace="0" name="xml" onLoad="rolloverLoad('xml','resources/button-xml-hi.gif','resources/button-xml-lo.gif');" src="resources/button-xml-lo.gif" vspace="0" width="96"></A></TD><TD align="left" height="20" valign="top" width="96"><A href="http://www.apache.org/" onMouseOut="rolloverOff('asf');" onMouseOver="rolloverOn('asf');" target="new"><IMG alt="http://www.apache.org/" border="0" height="20" hspace="0" name="asf" onLoad="rolloverLoad('asf','resources/button-asf-hi.gif','resources/button-asf-lo.gif');" src="resources/button-asf-lo.gif" vspace="0" width="96"></A></TD><TD align="left" height="20" valign="top" width="96"><A href="http://www.w3.org/" onMouseOut="rolloverOff('w3c');" onMouseOver="rolloverOn('w3c');" target="new"><IMG alt="http://www.w3.org/" border="0" height="20" hspace="0" name="w3c" onLoad="rolloverLoad('w3c','resources/button-w3c-hi.gif','resources/button-w3c-lo.gif');" src="resources/button-w3c-lo.gif" vspace="0" width="96"></A></TD></TR></TABLE><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD align="left" valign="top" width="120"><IMG alt="join" border="0" height="14" hspace="0" src="resources/join.gif" vspace="0" width="120"><BR> |
| |
| |
| |
| <A href="index.html" onMouseOut="rolloverOff('side-index');" onMouseOver="rolloverOn('side-index');"><IMG alt="Xalan-C++ 1.10" border="0" height="12" hspace="0" name="side-index" onLoad="rolloverLoad('side-index','graphics/index-label-2.jpg','graphics/index-label-3.jpg');" src="graphics/index-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="overview.html" onMouseOut="rolloverOff('side-overview');" onMouseOver="rolloverOn('side-overview');"><IMG alt="Overview" border="0" height="12" hspace="0" name="side-overview" onLoad="rolloverLoad('side-overview','graphics/overview-label-2.jpg','graphics/overview-label-3.jpg');" src="graphics/overview-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="charter.html" onMouseOut="rolloverOff('side-charter');" onMouseOver="rolloverOn('side-charter');"><IMG alt="Charter" border="0" height="12" hspace="0" name="side-charter" onLoad="rolloverLoad('side-charter','graphics/charter-label-2.jpg','graphics/charter-label-3.jpg');" src="graphics/charter-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| |
| <A href="whatsnew.html" onMouseOut="rolloverOff('side-whatsnew');" onMouseOver="rolloverOn('side-whatsnew');"><IMG alt="What's New" border="0" height="12" hspace="0" name="side-whatsnew" onLoad="rolloverLoad('side-whatsnew','graphics/whatsnew-label-2.jpg','graphics/whatsnew-label-3.jpg');" src="graphics/whatsnew-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="download.html" onMouseOut="rolloverOff('side-download');" onMouseOver="rolloverOn('side-download');"><IMG alt="Downloads" border="0" height="12" hspace="0" name="side-download" onLoad="rolloverLoad('side-download','graphics/download-label-2.jpg','graphics/download-label-3.jpg');" src="graphics/download-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="build_instruct.html" onMouseOut="rolloverOff('side-build_instruct');" onMouseOver="rolloverOn('side-build_instruct');"><IMG alt="Build Instructions" border="0" height="12" hspace="0" name="side-build_instruct" onLoad="rolloverLoad('side-build_instruct','graphics/build_instruct-label-2.jpg','graphics/build_instruct-label-3.jpg');" src="graphics/build_instruct-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="install.html" onMouseOut="rolloverOff('side-install');" onMouseOver="rolloverOn('side-install');"><IMG alt="Installation" border="0" height="12" hspace="0" name="side-install" onLoad="rolloverLoad('side-install','graphics/install-label-2.jpg','graphics/install-label-3.jpg');" src="graphics/install-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="samples.html" onMouseOut="rolloverOff('side-samples');" onMouseOver="rolloverOn('side-samples');"><IMG alt="Sample Apps" border="0" height="12" hspace="0" name="side-samples" onLoad="rolloverLoad('side-samples','graphics/samples-label-2.jpg','graphics/samples-label-3.jpg');" src="graphics/samples-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="commandline.html" onMouseOut="rolloverOff('side-commandline');" onMouseOver="rolloverOn('side-commandline');"><IMG alt="Command Line" border="0" height="12" hspace="0" name="side-commandline" onLoad="rolloverLoad('side-commandline','graphics/commandline-label-2.jpg','graphics/commandline-label-3.jpg');" src="graphics/commandline-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="usagepatterns.html" onMouseOut="rolloverOff('side-usagepatterns');" onMouseOver="rolloverOn('side-usagepatterns');"><IMG alt="Usage Patterns" border="0" height="12" hspace="0" name="side-usagepatterns" onLoad="rolloverLoad('side-usagepatterns','graphics/usagepatterns-label-2.jpg','graphics/usagepatterns-label-3.jpg');" src="graphics/usagepatterns-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="programming.html" onMouseOut="rolloverOff('side-programming');" onMouseOver="rolloverOn('side-programming');"><IMG alt="Programming" border="0" height="12" hspace="0" name="side-programming" onLoad="rolloverLoad('side-programming','graphics/programming-label-2.jpg','graphics/programming-label-3.jpg');" src="graphics/programming-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="Extensions" border="0" height="12" hspace="0" src="graphics/extensions-label-1.jpg" vspace="0" width="120"><BR> |
| |
| <A href="extensionslib.html" onMouseOut="rolloverOff('side-extensionslib');" onMouseOver="rolloverOn('side-extensionslib');"><IMG alt="Extensions Library" border="0" height="12" hspace="0" name="side-extensionslib" onLoad="rolloverLoad('side-extensionslib','graphics/extensionslib-label-2.jpg','graphics/extensionslib-label-3.jpg');" src="graphics/extensionslib-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="apiDocs/index.html" onMouseOut="rolloverOff('side-ext-36');" onMouseOver="rolloverOn('side-ext-36');"><IMG alt="API Reference" border="0" height="12" hspace="0" name="side-ext-36" onLoad="rolloverLoad('side-ext-36','graphics/ext-36-label-2.jpg','graphics/ext-36-label-3.jpg');" src="graphics/ext-36-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="faq.html" onMouseOut="rolloverOff('side-faq');" onMouseOver="rolloverOn('side-faq');"><IMG alt="FAQs" border="0" height="12" hspace="0" name="side-faq" onLoad="rolloverLoad('side-faq','graphics/faq-label-2.jpg','graphics/faq-label-3.jpg');" src="graphics/faq-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="separator" border="0" height="6" hspace="0" src="resources/separator.gif" vspace="0" width="120"><BR> |
| |
| <A href="whatsnew.html#bugs" onMouseOut="rolloverOff('side-ext-44');" onMouseOver="rolloverOn('side-ext-44');"><IMG alt="Bugs" border="0" height="12" hspace="0" name="side-ext-44" onLoad="rolloverLoad('side-ext-44','graphics/ext-44-label-2.jpg','graphics/ext-44-label-3.jpg');" src="graphics/ext-44-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <A href="./test/run.html#how-to-run-c" onMouseOut="rolloverOff('side-ext-46');" onMouseOver="rolloverOn('side-ext-46');"><IMG alt="Testing" border="0" height="12" hspace="0" name="side-ext-46" onLoad="rolloverLoad('side-ext-46','graphics/ext-46-label-2.jpg','graphics/ext-46-label-3.jpg');" src="graphics/ext-46-label-3.jpg" vspace="0" width="120"></A><BR> |
| |
| <IMG alt="close" border="0" height="14" hspace="0" src="resources/close.gif" vspace="0" width="120"><BR></TD><TD align="left" valign="top" width="500"><TABLE border="0" cellpadding="3" cellspacing="0"><TR><TD> |
| <UL> |
| <LI><A href="#intro">Introduction</A></LI> |
| <LI><A href="#implement">Implementing an extension function</A></LI> |
| <LI><A href="#install">Installing an extension function</A></LI> |
| <LI><A href="#use">Using an extension function</A></LI> |
| </UL> |
| <A name="intro"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Introduction</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| <P>At times, you may want to call your own custom C functions from a stylesheet. For these situations, Xalan-C++ supports the |
| creation and use of extension functions. Xalan-C++ also provides a <A href="extensionslib.html">library of extension functions |
| </A> for your use.</P> |
| <P>You can think of extension functions as extending the core library of functions that XPath provides. Like the |
| XPath functions, an extension function returns an XObject, which may contain a value of any of the five XSLT |
| data types: node-set, result-tree-fragment, string, boolean, or number.</P> |
| <P>You can send arguments to an extension function in the form of XPath expressions, literals (for string, boolean, and number), |
| the values returned by other functions, and XSL variables or parameters set to any of the preceding.</P> |
| <P>For an example that implements, installs, and uses three extension functions, see the |
| <A href="samples.html#externalfunctions">External Functions</A> sample.</P> |
| <TABLE border="0" cellpadding="0" cellspacing="3" width="100%"><TR><TD valign="top" width="20"><IMG alt="Note" border="0" height="24" hspace="0" src="resources/note.gif" vspace="0" width="20"></TD><TD valign="top"><FONT color="#000000" face="arial,helvetica,sanserif" size="-1"><I>Xalan-C++ does not support extension elements.</I></FONT></TD></TR></TABLE> |
| </FONT></TD></TR></TABLE><BR> |
| |
| <A name="implement"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Implementing an extension function</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| <P>Like the standard XPath functions, the functions you create derive from the Function base class. Set up your |
| extension function class as follows:</P> |
| <OL> |
| <LI>The body of a function is the execute() method. Use the appropriate XObjectFactory method -- createNumber() |
| in the example below -- to create an XObject corresponding to the XSLT data type the function returns.<BR><BR></LI> |
| <LI>Implement a clone() method to enable Xalan to create and maintain a copy of the extension |
| function.<BR><BR></LI> |
| <LI>(Optional) As Xalan does for the XPath functions, you may want to prevent the compiler from generating |
| an assignment or equality operator for this function.</LI> |
| </OL> |
| <P>These features all appear in the following example.</P> |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| // Base header file. Must be first. |
| #include <xalanc/Include/PlatformDefinitions.hpp> |
| |
| #include <cmath> |
| #include <ctime> |
| |
| #include <xercesc/util/PlatformUtils.hpp> |
| #include <xalanc/XalanTransformer/XalanTransformer.hpp> |
| #include <xalanc/XPath/XObjectFactory.hpp> |
| |
| XALAN_CPP_NAMESPACE_USE |
| |
| // This class defines a function that will return the square root |
| // of its argument. |
| class FunctionSquareRoot : public Function |
| { |
| public: |
| |
| /** |
| * Execute an XPath function object. The function must return a valid |
| * XObject. |
| * |
| * @param executionContext executing context |
| * @param context current context node |
| * @param opPos current op position |
| * @param args vector of pointers to XObject arguments |
| * @return pointer to the result XObject |
| */ |
| virtual XObjectPtr |
| execute( |
| XPathExecutionContext& executionContext, |
| XalanNode* /* context */, |
| const XObjectPtr arg, |
| const Locator* /* locator */) const |
| { |
| if (args.size() != 1) |
| { |
| executionContext.error("The square-root() function takes one argument!", |
| context); |
| } |
| assert(args[0] != 0); |
| // Use the XObjectFactory createNumber() method to create an XObject |
| // corresponding to the XSLT number data type. |
| return executionContext.getXObjectFactory().createNumber( |
| sqrt(args[0]->num())); |
| } |
| |
| /** |
| * Implement clone() so Xalan can copy the square-root function into |
| * its own function table. |
| * |
| * @return pointer to the new object |
| */ |
| // For compilers that do not support covariant return types, |
| // clone() must be declared to return the base type. |
| #if defined(XALAN_NO_COVARIANT_RETURN_TYPE) |
| virtual Function* |
| #else |
| virtual FunctionSquareRoot* |
| #endif |
| clone() const |
| { |
| return new FunctionSquareRoot(*this); |
| } |
| |
| private: |
| // The assignment and equality operators are not implemented... |
| FunctionSquareRoot& |
| operator=(const FunctionSquareRoot&); |
| bool |
| operator==(const FunctionSquareRoot&) const; |
| } |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| </FONT></TD></TR></TABLE><BR> |
| <A name="install"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Installing an extension function</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| <P><A href="apiDocs/classXalanTransformer.html">XalanTransformer</A> provides methods for installing and uninstalling external functions:</P> |
| <UL> |
| <LI>installExternalFunction() makes the function available in the current instance of XalanTransformer. Use uninstallExternalFunction() to remove the function.<BR><BR></LI> |
| <LI>installExternalFunctionGlobal() makes the function available globally. Use uninstallExternalFunctionGlobal() to remove the function. The global install and uninstall operations are not thread-safe. However, all global functions should be thread-safe, because multiple threads could call a particular function instance at the same time.</LI> |
| </UL> |
| <P>These methods include arguments for the namespace, the function name, and the function implementation.</P> |
| <P>When you install an extension function, the function inhabits the namespace you designate. For information about XML namespaces, see <A href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML</A>.</P> |
| <P>The following code fragment installs locally the square root function defined above, and binds it to the extension-function name "square-root" in the namespace "http://MyExternalFunction.mycompany.org" so it can be accessed from stylesheets. Keep in mind that the function name does not need to be the same as the name of the function class, and that a function name may be used more than once provided that each function with that name is installed in a different namespace.</P> |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE>#include <xalanc/Include/PlatformDefinitions.hpp> |
| #include <xercesc/util/PlatformUtils.hpp> |
| #include <xalanc/XalanTransformer/XalanTransformer.hpp> |
| // You have created a header file for FunctionSquareRoot. |
| #include <MyFunctions/FunctionSquareRoot.hpp> |
| // The namespace... |
| const XalanDOMString |
| theNamespace("http://MyExternalFunction.mycompany.org"); |
| |
| theXalanTransformer.installExternalFunction(theNamespace, |
| XalanDOMString("square-root"), |
| FunctionSquareRoot());</PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| <P>For an example that installs three functions, see the <A href="samples.html#externalfunctions">External Functions</A> sample.</P> |
| </FONT></TD></TR></TABLE><BR> |
| <A name="use"><!--anchor--></A> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="666699" colspan="2" width="494"><TABLE border="0" cellpadding="0" cellspacing="0" width="494"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="492"><FONT color="#ffffff" face="arial,helvetica,sanserif" size="+1"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Using an extension function</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="492"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="492"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="484"><FONT color="#000000" face="arial,helvetica,sanserif"> |
| <P>To use the extension function in a stylesheet, you must do the following:</P> |
| <OL> |
| <LI>Declare the extension function namespace.<BR><BR> |
| <CODE><FONT face="courier, monospaced">xmlns:<I>prefix</I>=<I>URI</I></FONT></CODE><BR><BR> |
| The <I>prefix</I> identifies the namespace, and <I>URI</I> matches the namespace specified when the function |
| is installed.<BR><BR> |
| By default, namespace declarations are included in the transformation output. To exclude namespaces from the output, |
| use<BR><BR> |
| <CODE><FONT face="courier, monospaced">exclude-result-prefixes="<I>prefix-1 prefix-2 ...</I>"</FONT></CODE><BR><BR> |
| in the stylesheet element or<BR><BR> |
| <CODE><FONT face="courier, monospaced">xsl:exclude-result-prefixes="<I>prefix-1 prefix-2 ...</I>"</FONT></CODE><BR><BR> |
| in a literal result element or extension element.<BR><BR></LI> |
| <LI>Call the extension function in the same manner you would call an XPath function. The function name you use in the stylesheet is a Qualified Name (QName) made up of the prefix you declared in step 1 and the function name you specified when you installed the function.<BR><BR> |
| You can use XPath expressions, literals (for string, boolean, and number), and values returned by other functions to |
| specify function arguments.</LI></OL> |
| <P>Suppose, for example, you are working with XML documents containing area elements like |
| <CODE><FONT face="courier, monospaced"><area value="397"/></FONT></CODE>, where the value attribute identifies the area of a square.</P> |
| <P>The following stylesheet declares the square-root function namespace (the prefix is up to you), instructs |
| the processor not to copy the namespace declaration to the result tree, and uses the square-root function to return |
| the square root of //area/@value:</P> |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE> |
| <?xml version="1.0"?> |
| <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" |
| version="1.0" |
| xmlns:external="http://ExternalFunction.xalan-c.xml.apache.org" |
| exclude-result-prefixes="external"> |
| |
| <xsl:template match="//area"> |
| <out> |
| The area of the square is |
| <xsl:value-of select="@value"/> square units. |
| The length of each side is |
| <xsl:value-of select="external:square-root(@value)"/> units |
| </out> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| <P>This stylesheet converts <CODE><FONT face="courier, monospaced"><area value="397"/></FONT></CODE> into the following output:</P> |
| <DIV align="right"><TABLE border="0" cellpadding="0" cellspacing="4" width="464"><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#ffffff" width="462"><FONT size="-1"><PRE><out> |
| The area of the square is |
| 397 square units. |
| The length of each side is |
| 19.9249 units. |
| </out> |
| </PRE></FONT></TD><TD bgcolor="#0086b2" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" height="1" width="462"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="462"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></DIV> |
| <P>For a slightly more complex variation on this example, |
| see the <A href="samples.html#externalfunctions">External Functions</A> sample.</P> |
| <TABLE border="0" cellpadding="0" cellspacing="0" width="484"><TR><TD bgcolor="666699" colspan="2" width="484"><TABLE border="0" cellpadding="0" cellspacing="0" width="484"><TR><TD bgcolor="#039acc" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#039acc" height="1" width="482"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="482"></TD><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#039acc" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#0086b2" width="482"><FONT color="#ffffff" face="arial,helvetica,sanserif"><IMG alt="" border="0" height="2" hspace="0" src="resources/void.gif" vspace="0" width="2"><B>Passing Nodes to a function</B></FONT></TD><TD bgcolor="#017299" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR><TR><TD bgcolor="#0086b2" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD><TD bgcolor="#017299" height="1" width="482"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="482"></TD><TD bgcolor="#017299" height="1" width="1"><IMG alt="" border="0" height="1" hspace="0" src="resources/void.gif" vspace="0" width="1"></TD></TR></TABLE></TD></TR><TR><TD width="10"> </TD><TD width="474"><FONT color="#000000" face="arial,helvetica,sanserif" size="-1"> |
| <P>Please keep in mind that <B>all</B> LocationPath expressions return a node-set, even if the expression only |
| returns a single attribute or a text node (node-sets with one member). You can use the XSLT string() function |
| to convert a node-set value to string, and the number() function to convert a node-set value to number (a double).</P> |
| <P>If you pass a node-set to an extension function, be sure to set up the function to process a node-set.</P> |
| <P>Suppose, for example, you have a ProcessNodes function class that uses<BR><BR> |
| <CODE><FONT face="courier, monospaced">const NodeRefListBase& theNodeList = args[0]->nodeset();</FONT></CODE><BR><BR> |
| in the execute() method to get a reference to the node-set.</P> |
| <P>Assuming you install the function as "ProcessNodes" and use the "node-ext" prefix in a stylesheet to refer to the ProcessNodes function namespace, any of the following function calls are syntactically possible:</P> |
| <P><CODE><FONT face="courier, monospaced"><!--Process the current node--></FONT></CODE><BR> |
| <CODE><FONT face="courier, monospaced"><xsl:variable name="success" select="node-ext:ProcessNodes(.)"/></FONT></CODE></P> |
| <P><CODE><FONT face="courier, monospaced"><!--Process all nodes in current context--></FONT></CODE><BR> |
| <CODE><FONT face="courier, monospaced"><xsl:variable name="success" select="node-ext:ProcessNodes(*)"/></FONT></CODE></P> |
| <P><CODE><FONT face="courier, monospaced"><!-- Process all nodes --></FONT></CODE><BR> |
| <CODE><FONT face="courier, monospaced"><xsl:variable name="success" select="node-ext:ProcessNodes(/*)"/></FONT></CODE></P> |
| <P><CODE><FONT face="courier, monospaced"><!--Process the foo/baz nodes in current context --></FONT></CODE><BR> |
| <CODE><FONT face="courier, monospaced"><xsl:variable name="success" select="node-ext:ProcessNodes(foo/baz)"/></FONT></CODE></P> |
| <P><CODE><FONT face="courier, monospaced"><!--Process the/foo/baz and /bar/saz nodes --></FONT></CODE><BR> |
| <CODE><FONT face="courier, monospaced"><xsl:variable name="success" select="node-ext:ProcessNodes(/foo/baz | /bar/saz)"/></FONT></CODE></P> |
| <P>The NodeRefListBase is in fact a list of references into the XML document, so keep in mind that getNextSibling(), |
| for example, gets you the next sibling in the document, which may not be the next Node in the node-set.</P> |
| </FONT></TD></TR></TABLE><BR> |
| </FONT></TD></TR></TABLE><BR> |
| </TD></TR></TABLE></TD></TR></TABLE><BR><TABLE border="0" cellpadding="0" cellspacing="0" width="620"><TR><TD bgcolor="#0086b2"><IMG alt="dot" height="1" src="images/dot.gif" width="1"></TD></TR><TR><TD align="center"><FONT color="#0086b2" size="-1"><I> |
| Copyright © 1999-2004 The Apache Software Foundation. |
| All Rights Reserved. |
| </I></FONT></TD></TR></TABLE></BODY></HTML> |