




















|
| |
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.
|
 |  |  |  | Using the XalanTransformer class |  |  |  |  |
| |
Xalan-C++ 1.1 introduces XalanTransformer, a new class designed to package the basic Xalan infrastructure and provide a simpler C++
and C API for performing standard transformations.
 | As we expand the functionality of the XalanTransformer, we will revise the remainder of this chapter and the samples to indicate
how to take advantage of the API it provides. |
 |  |  |  | Variations with the XalanTransformer C++ API |  |  |  |  |
| |
The XalanTransformer transform() methods also allow you to process and produce streams, and to send the output in blocks to a callback
function, which means you can begin processing the output while the transformation is still in progress. Each transform() method returns
an integer code, 0 for success. If an error occurs, you can use the getLastError() method to return a pointer to the error message.
For the details, see XalanTransormer/XalanTransformer.hpp in the source tree. For an example, see the
XalanTransform sample.
Transform an XML file with a stylesheet processing instruction to an output file.
 |  |  |  | int
transform(const char* xmlInFile,
const char* xmlOutFile); |  |  |  |  |
Transform from files to an output stream:
 |  |  |  | int
transform(const char* xmlInFile,
const char* xslFile,
ostream& resultOutStream); |  |  |  |  |
Transform from input streams to an output stream:
 |  |  |  | int
transform(istream& xmlInStream,
istream& xslInStram,
ostream& resultOutStream); |  |  |  |  |
Transform an input stream that contains the XML input with a stylesheet processing instruction to an output stream.
 |  |  |  | int
transform(istream& xmlInStream,
ostream& resultOutStream); |  |  |  |  |
Transform from files to an output handler that receives the output in blocks.
 |  |  |  | int
transform(const char* xmlInFile,
const char* xslFile,
const void* theOutputHandle,
XalanOutputHandlerType theOutputHandler
XalanFlushHanderType theFlushHandler = 0); |  |  |  |  |
The transform() method that the other transform() methods all call:
 |  |  |  | int
transform( const XSLTInputSource& xmlInput,
const XSLTInputSource& xslStylesheet,
const XSLTResultTarget& transformResult); |  |  |  |  |
|
 |  |  |  | Variations with the XalanTransformer C API |  |  |  |  |
| |
The C API supports basically the same options as the C++ API.
Transform from files to a character array:
 |  |  |  | int
XalanTransformToData(const char* xmlInFile,
const char* xslFile,
const char** transformOutput,
XalanHandle xalan); |  |  |  |  |
If the XML input contains a stylesheet processing instruction that you want to use, include an empty string ("") for the xslFile argument.
After calling XalanTransformToData(), call XalanFreeData() with the address of the pointer to the character array:
XalanFreeData(transformOutput);
Transform to a callback function that receives the output in blocks (see the ApacheModuleXSLT sample).
 |  |  |  | int
XalanTransformToHandler(const char* xmlInFile,
const char* xslFile,
XalanHandle xalan,
const void* outputHandle,
XalanOutputHandlerType outputHandler,
XalanFlushHandlerType flushHandler); |  |  |  |  |
|
|
 |  |  |  | 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 factory support object, independent of the XPath support object for an XSLT processor. So after you have set up the XSLT processor with its support objects, set up another XPath
factory support object and use it 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.
- 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++ implements Unicode-style collation.
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, AIX, or HP-UX 11: 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_1.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_1.a with XALAN_USE_ICU defined, and place it on the load library
path (LIBPATH) or copy it to /usr/lib.
For HP-UX 11, rebuild libxalan-c1_1.sl with XALAN_USE_ICU defined, and place it on the shared library
path (SHLIB_PATH) or copy it to /usr/lib.
For Solaris, rebuild libxalan-c1_1.so with XALAN_USE_ICU defined, and place it on the shared library
path (LD_LIBRARY_PATH) or copy it to /usr/lib.
Number formatting
To enable ICU support for the XSLT format-number() function, do
the following:
 |  |  |  | // Install ICU support for the format-number() function.
FunctionICUFormatNumber::FunctionICUFormatNumberInstaller theInstaller; |  |  |  |  |
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); |  |  |  |  |
|
|
|
|