



















|
| |
Xalan-C++ takes as primary input an XML source document and an XSL stylesheet, both represented by instances of XSLTInputSource. These input objects may each take the form of a file or URL, a stream, or a DOM tree. The stylesheet may also take the form of a compiled stylesheet (an instance of StylesheetRoot).
 | If the XML source document contains a stylesheet Processing Instruction (PI), Xalan-C++ uses the stylesheet this PI points to and a separate stylesheet object is not required. |
Xalan-C++ uses Xerces-C++ to parse text input, performs the transformation, and sends the output to an instance of XSLTResultTarget, which may be configured to write to a file, a stream, or a DOM tree.
For detailed API documentation, see Xalan-C++ API. For an overview of the
command-line utility, see Command-Line Utility.
|
 |  |  |  | Setting stylesheet parameters |  |  |  |  |
| |
An XSL stylesheet can include parameters that are set at run time before a transformation takes place. When we generate the HTML documents that make up the Xalan doc set, for example, we send the stylesheet an id parameter along with each XML source document. The id identifies that document and enables the stylesheet to integrate it into the overall doc set.
To set a stylesheet parameter, use one of the XSLTEngineImpl setStylesheetParam() methods. Both methods take two arguments: the parameter name (a XalanDOMstring) and the expression (a XalanDOMString or an XObject). The XObject option is useful when you are working with the XPath API. For example, you could use the XObject returned by an Xpath function to set a stylesheet parameter.
 | If the expression is a string and you are using XalanDOMString for the input parameter, enclose it in single quotes to make it a string expression. |
You can include the -param flag with two arguments when you call the command line utility. The first argument is the parameter name or key, and the second argument is the string expression (in single quotes). For example:
TestXSLT -in foo.xml -xsl foo.xsl -param param1 'boo'
If the string expression includes spaces or other characters that the shell intercepts, first enclose the string in single quotes so Xalan-C++ interprets it as a string expression, and then enclose the resulting string in double quotes so the shell interprets it as a single argument. For example:
TestXSLT -in foo.xml -xsl foo.xsl -param param1 "'hello there'"
The UseStylesheetParam sample application also uses a command-line parameter.
|
| |
When Xalan-C++ performs a transformation with the XSLTEngineImpl process() method used above, it starts by compiling the stylesheet into a binary representation. If you intend to use the same stylesheet to perform multiple transformations, you can enhance efficiency by explicitly compiling the stylesheet and using another XSLTEngimeImpl process() method for each transformation. A compiled stylesheet (a StylesheetRoot object) is thread safe, so it even supports concurrent access by multiple clients. If, for example, you are setting up a server application to perform transformations, you can improve performance by compiling any stylesheets the application repeatedly uses.
A compiled stylesheet requires its own XPath and XObject factory support objects, independent of the support objects for an XSLT processor. So after you have set up the XSLT processor with its support objects, set up other
factory support objects and use them to create a construction context for the stylesheet:
 |  |  |  | // Set up the XSLT processor with its support objects
XercesDOMSupport theDOMSupport;
XercesParserLiaison theParserLiaison(theDOMSupport);
XPathSupportDefault theXPathSupport(theDOMSupport);
XSLTProcessorEnvSupportDefault theXSLTProcessorEnvSupport;
XObjectFactoryDefault theXObjectFactory;
XPathFactoryDefault theXPathFactory;
// Create the processor and connect to the
// environment support object.
XSLTEngineImpl theProcessor(
theParserLiaison,
theXPathSupport,
theXSLTProcessorEnvSupport,
theDOMSupport;
theXObjectFactory,
theXPathFactory);
theXSLTProcessorEnvSupport.setProcessor(&theProcessor);
...
// Create an XPath factory support object for the stylesheet,
// so it will have its own factory-created XPath instances
// (separate from the XSLT processor XPath objects).
XPathFactoryDefault theStylesheetXPathFactory;
// Use this XPath factory support object to create a stylesheet
// construction context.
StylesheetConstructionContextDefault theConstructionContext(
theProcessor,
theXSLTProcessorEnvSupport,
theStylesheetXPathFactory);
// The execution context uses the same factory support objects as
// the processor.
StylesheetExecutionContextDefault theExecutionContext(
theProcessor,
theXSLTProcessorEnvSupport,
theXPathSupport,
theXObjectFactory); |  |  |  |  |
Compile the stylesheet, add the StylesheetRoot object to the execution context, and start performing transformations. Use the XSLTEngineImpl process() method (see below) that takes advantage of the compiled stylesheet. Be sure to reset the processor and execution context between each transformation. For example:
 |  |  |  |
// Compile the stylesheet.
StylesheetRoot* const theStylesheetRoot =
theProcessor.processStylesheet(
theStylesheetSource,
theConstructionContext);
assert(theStylesheetRoot != 0);
// Set the execution context object to use the compiled stylesheet.
theExecutionContext.setStylesheetRoot(theStylesheetRoot)
// Set up an XSLTInputSource object (theInputSource)
// and an XSLTResultTarget object (theResultTarget).
...
// Do the transformation. This version of the process() method uses
// the StylesheetRoot object associated with the execution context.
theProcessor.process(
theInputSource,
theResultTarget,
theExecutionContext);
// Reset the processor and the execution context
// so we can perform the next transformation.
// Reset the parser liaison to clear out the
// source document we just transformed.
theProcessor.reset();
theExecutionContext.reset();
theParserLiaison.reset();
theExecutionContext.setStylesheetRoot(theStylesheetRoot);
// Perform the next transformation.
.... |  |  |  |  |
For an example, see the CompileStylesheet sample.
|
| |
TraceListener is a debugging abstract base class implemented by TraceListenerDefault. You can use TraceListener to trace any combination of the following:
- Calls to templates
- Calls to template children
- Selection events
- Result tree generation events
To construct a TraceListener with TraceListenerDefault, you need a PrintWriter and a boolean for each of these four tracing options. You can then use the XSLTEngimeImpl setTraceSelects and addTraceListener methods to add the TraceListener to an XSLTProcessor. See the TraceListen sample application.
The command-line utility (TextXSLT) and TraceListen both use TraceListenerDefault to write events to the screen.
|
| |
You can use the International Components for Unicode (ICU) to extend support for encoding, number
formatting, and sorting.
- Encoding
Xerces-C++ and Xalan-C++ use UTF-16 encoding to work with Unicode data.
If you integrate the ICU with Xerces-C++, both Xerces-C++ and Xalan-C++ use ICU support for
UTF-16 encoding.
- xsl:number element
Both Xalan-C++ and the ICU provide a complete implementation for
xsl:number.
- format-number()
This XSLT function includes two or three arguments (the third is
optional): number, format pattern, and decimal-format name. Xalan-C++ ignores the format
pattern and optional decimal-format name. If you install ICU support for format-number(),
this function is fully supported with all its arguments.
- xsl:sort
If you install ICU support for xml:sort, Xalan-C++ applies the Unicode sorting
algorithm.
To get the ICU:
- Download and unzip the International Components for Unicode (ICU) 1.6 source files from the IBM
developerWorks open source zone.
- Do an ICU build -- see the Windows NT or Unix build instructions in the readme.html that
accompanies the download.
Important For Windows, be sure to install the ICU on the same drive and at
the same level as Xalan-C++ and Xerces-C++.
- Set the ICU_DATA environment variable as indicated in the readme.html.
 |  |  |  | Enabling ICU support for number formatting and sorting |  |  |  |  |
| |
If you only want to use the ICU to support number formatting and sorting, you do not need to
integrate the ICU with Xalan-C++, but you must do the following in the application where you
want to enable ICU support:
- Include the ICUBridge headers.
- Substitute ICU support for format-number(), xsl:number, and/or xsl:sort.
- Windows: Provide your application access to the ICUBridge library.
Linux or AIX: Rebuild the Xalan library to include the ICUBridge.
ICUBridge
All Xalan-C++ references to ICU are centralized in the ICUBridge module, which supplies the
infrastructure for enabling ICU support for number formatting and sorting.
 |  |  |  | #include <ICUBridge/ICUBridge.hpp>
#include <ICUBridge/FunctionICUFormatNumber.hpp>
#include <ICUBridge/ICUXalanNumberFormatFactory.hpp>
#include <ICUBridge/ICUBridgeCollationCompareFunctor.hpp> |  |  |  |  |
For Windows be sure ICUBridge.dll,the ICUBridge library, is on the path.
For Linux, rebuild libxalan-c1_0.so with XALAN_USE_ICU defined, and place it on the shared library path
(LD_LIBRARY_PATH for Red Hat Linux 6.1) or copy it to /usr/lib.
For AIX, rebuild libxalan-c1_0.so/libxalan-c1_0.a with XALAN_USE_ICU defined, and place it on the load library
path (LIB_PATH) or copy it to /usr/lib.
Number formatting
To enable ICU support for the xsl:number element and the XSLT format-number() function, do
the following:
 |  |  |  | // Install ICU support for the format-number() function.
FunctionICUFormatNumber::FunctionICUFormatNumberInstaller theInstaller;
// Create and install a factory for using the ICU for xsl:number.
ICUXalanNumberFormatFactory theXalanNumberFormatFactory;
StylesheetExecutionContextDefault::installXalanNumberFormatFactory
(&theXalanNumberFormatFactory); |  |  |  |  |
Sorting
To enable ICU support for xsl:sort, do the following:
 |  |  |  | // Set up a StylesheetExecutionContextDefault object
// (named theExecutionContext in the following fragment),
// and install the ICUCollationCompareFunctor.
ICUBridgeCollationCompareFunctor theICUFunctor;
theExecutionContext.installCollationCompareFunctor(&theICUFunctor); |  |  |  |  |
|
|
|
|