blob: 3fa0ab72254979ae324273028a2770f043b58f0e [file] [log] [blame]
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 1999-2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#include <Include/PlatformDefinitions.hpp>
#include <cstdio>
#include <cstring>
#if defined(XALAN_OLD_STREAM_HEADERS)
#include <iostream.h>
#else
#include <iostream>
#endif
#if !defined(NDEBUG) && defined(_MSC_VER)
#include <crtdbg.h>
#endif
#include <util/PlatformUtils.hpp>
#include <sax/SAXParseException.hpp>
#include <XalanDOM/XalanDOMException.hpp>
#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/DOMStringPrintWriter.hpp>
#include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>
#include <PlatformSupport/XalanFileOutputStream.hpp>
#include <PlatformSupport/XalanStdOutputStream.hpp>
#include <Include/XalanAutoPtr.hpp>
#include <DOMSupport/DOMSupportDefault.hpp>
#include <XPath/XObjectFactoryDefault.hpp>
#include <XPath/XPathEnvSupportDefault.hpp>
#include <XPath/XPath.hpp>
#include <XPath/XPathExecutionContextDefault.hpp>
#include <XPath/XPathFactoryBlock.hpp>
#include <XPath/XPathFactoryDefault.hpp>
#include <XPath/XPathProcessorImpl.hpp>
#include <XalanExtensions/XalanExtensions.hpp>
#include <XercesParserLiaison/XercesParserLiaison.hpp>
#include <XercesParserLiaison/XercesDOMSupport.hpp>
#include <XMLSupport/FormatterToDOM.hpp>
#include <XMLSupport/FormatterToHTML.hpp>
#include <XMLSupport/FormatterToNull.hpp>
#include <XMLSupport/FormatterToText.hpp>
#include <XMLSupport/FormatterToXML.hpp>
#include <XMLSupport/FormatterTreeWalker.hpp>
#include <XalanSourceTree/FormatterToSourceTree.hpp>
#include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
#include <XalanSourceTree/XalanSourceTreeDocument.hpp>
#include <XalanSourceTree/XalanSourceTreeInit.hpp>
#include <XalanSourceTree/XalanSourceTreeParserLiaison.hpp>
#include <XSLT/XSLTEngineImpl.hpp>
#include <XSLT/XSLTInit.hpp>
#include <XSLT/XSLTInputSource.hpp>
#include <XSLT/XSLTResultTarget.hpp>
#include <XSLT/StylesheetRoot.hpp>
#include <XSLT/StylesheetConstructionContextDefault.hpp>
#include <XSLT/StylesheetExecutionContextDefault.hpp>
#include <XSLT/TraceListenerDefault.hpp>
#include <XSLT/XSLTProcessorEnvSupportDefault.hpp>
#define XALAN_USE_ICU
#if defined(XALAN_USE_ICU)
#include <ICUBridge/FunctionICUFormatNumber.hpp>
#include <ICUBridge/ICUBridgeCollationCompareFunctor.hpp>
#endif
//#define XALAN_VQ_SPECIAL_TRACE
#if defined(XALAN_VQ_SPECIAL_TRACE)
#include "C:/Program Files/Rational/Quantify/pure.h"
#endif
#if !defined (XALAN_NO_NAMESPACES)
using std::cerr;
using std::cin;
using std::cout;
using std::endl;
using std::hex;
using std::pair;
using std::vector;
#endif
/**
* Print argument options.
*/
void
printArgOptions()
{
cerr << endl
<< "TestXSLT options: "
<< endl
<< endl
<< "Options are not case-sensitive."
<< endl
<< endl
<< " [-? Shows this message.]"
<< endl
<< endl
<< " [-h Shows this message.]"
<< endl
<< endl
<< " [-IN inputXMLURL (If not specified, stdin is used.)]"
<< endl
<< endl
<< " [-XSL XSLTransformationURL]"
<< endl
<< " [-OUT outputFileName]"
<< endl
<< " [-V (Show version information only.)]"
<< endl
<< " [-QC (Quiet pattern conflicts warnings.)]"
<< endl
<< " [-Q (Use quiet mode.)]"
<< endl
<< " [-INDENT n (Controls how many spaces to indent. {default is 0})]"
<< endl
<< " [-VALIDATE (Controls whether validation occurs. Validation is off by default.)]"
<< endl
<< endl
<< " [-TT (Trace the templates as they are being called.)]"
<< endl
<< " [-TG (Trace each generation event.)]"
<< endl
<< " [-TS (Trace each selection event.)]"
<< endl
<< " [-TTC (Trace the template children as they are being processed.)]"
<< endl
<< endl
<< " [-XML (Use XML formatter and add XML header.)]"
<< endl
<< " [-TEXT (Use Text formatter.)]"
<< endl
<< " [-HTML (Use HTML formatter.)]"
<< endl
<< " [-DOM (Use DOM formatter. Formats to DOM, then formats XML for output.)]"
<< endl
<< " [-XST (Use source tree formatter. Formats to Xalan source tree, then formats XML for output.)]"
<< endl
<< endl
<< " [-PARAM name expression (Sets a stylesheet parameter.)]"
<< endl
<< endl
<< " [-XD (Use Xerces DOM instead of Xalan source tree.)]"
<< endl
<< endl
<< " [-DE (Disable built-in extension functions.)]"
<< endl
<< " [-EN (Specify the namespace URI for Xalan extension functions. The default is 'http://xml.apache.org/xalan')]"
<< endl
<< endl
<< "The following options are valid only with -HTML or -XML."
<< endl
<< endl
<< " [-STRIPCDATA (Strip CDATA sections of their brackets, but don't escape.)"
<< endl
<< " [-ESCAPECDATA (Strip CDATA sections of their brackets, but escape.)"
<< endl
<< endl
<< "The following option is valid only with -HTML."
<< endl
<< endl
<< " [-NOINDENT (Turns off HTML indenting..]"
<< endl
<< endl
<< "The following option is valid only with -XML."
<< endl
<< endl
<< " [-NH (Don't write XML header.)]"
<< endl;
}
typedef vector<pair<const char*, const char*> > StringPairVectorType;
struct CmdLineParams
{
StringPairVectorType params;
bool escapeCData;
bool setQuietConflictWarnings;
bool setQuietMode;
bool stripCData;
bool versionOnly;
bool traceTemplates;
bool traceGenerationEvent;
bool traceSelectionEvent;
bool traceTemplateChildren;
bool shouldWriteXMLHeader;
bool doValidation;
bool noIndent;
bool formatToNull;
bool formatToSourceTree;
bool useDOM;
bool disableExtensions;
int indentAmount;
int outputType;
const char* outFileName;
const char* xslFileName;
const char* inFileName;
const char* extentionsNamespace;
CmdLineParams() :
params(),
escapeCData(false),
setQuietConflictWarnings(false),
setQuietMode(false),
stripCData(false),
versionOnly(false),
traceTemplates(false),
traceGenerationEvent(false),
traceSelectionEvent(false),
traceTemplateChildren(false),
shouldWriteXMLHeader(true),
doValidation(false),
noIndent(false),
formatToNull(false),
formatToSourceTree(false),
useDOM(false),
disableExtensions(false),
indentAmount(-1),
outputType(-1),
outFileName(0),
xslFileName(0),
inFileName(0),
extentionsNamespace(0)
{
}
};
void
warnPreviousOutputMethod(int outputMethod)
{
cerr << endl << "Warning: Ignoring previous output method switch ";
switch(outputMethod)
{
case FormatterListener::OUTPUT_METHOD_XML:
cerr << "-XML.";
break;
case FormatterListener::OUTPUT_METHOD_TEXT:
cerr << "-TEXT.";
break;
case FormatterListener::OUTPUT_METHOD_HTML:
cerr << "-HTML.";
break;
case FormatterListener::OUTPUT_METHOD_DOM:
cerr << "-DOM.";
break;
}
cerr << endl << endl;
}
#if defined(OS390)
#include <strings.h>
int
compareNoCase(
const char* str1,
const char* str2)
{
return strcasecmp(str1, str2);
}
#else
int
compareNoCase(
const char* str1,
const char* str2)
{
return stricmp(str1, str2);
}
#endif
bool
getArgs(
int argc,
const char* argv[],
CmdLineParams& p)
{
bool fSuccess = true;
for (int i = 1; i < argc && fSuccess == true; ++i)
{
if (!compareNoCase("-h", argv[i]) || !compareNoCase("-?", argv[i]))
{
fSuccess = false;
}
else if (!compareNoCase("-IN", argv[i]))
{
++i;
if(i < argc && argv[i][0] != '-')
{
p.inFileName = argv[i];
}
else
{
fSuccess = false;
}
}
else if (!compareNoCase("-XSL", argv[i]))
{
++i;
if(i < argc && argv[i][0] != '-')
{
p.xslFileName = argv[i];
}
else
{
fSuccess = false;
}
}
else if (!compareNoCase("-OUT", argv[i]))
{
++i;
if(i < argc && argv[i][0] != '-')
{
p.outFileName = argv[i];
}
else
{
fSuccess = false;
}
}
else if (!compareNoCase("-NOINDENT", argv[i]))
{
p.noIndent = true;
}
else if (!compareNoCase("-INDENT", argv[i]))
{
++i;
if(i < argc && argv[i][0] != '-')
{
p.indentAmount = atoi(argv[i]);
}
else
{
fSuccess = false;
}
}
else if(!compareNoCase("-VALIDATE", argv[i]))
{
p.doValidation = true;
}
else if (!compareNoCase("-PARAM", argv[i]))
{
++i;
if(i < argc && argv[i][0] != '-')
{
const char* const name = argv[i];
++i;
// Don't check for '-' here, since that might
// be a valid character in a parameter value.
if(i < argc)
{
typedef StringPairVectorType::value_type value_type;
p.params.push_back(value_type(name, argv[i]));
}
else
{
fSuccess = false;
}
}
else
{
fSuccess = false;
}
}
else if(!compareNoCase("-V", argv[i]))
{
p.versionOnly = true;
}
else if(!compareNoCase("-QC", argv[i]))
{
p.setQuietConflictWarnings = true;
}
else if(!compareNoCase("-Q", argv[i]))
{
p.setQuietMode = true;
}
else if(!compareNoCase("-XML", argv[i]))
{
if (p.outputType != -1)
{
warnPreviousOutputMethod(p.outputType);
}
p.outputType = FormatterListener::OUTPUT_METHOD_XML;
}
else if(!compareNoCase("-TEXT", argv[i]))
{
if (p.outputType != -1)
{
warnPreviousOutputMethod(p.outputType);
}
p.outputType = FormatterListener::OUTPUT_METHOD_TEXT;
}
else if(!compareNoCase("-HTML", argv[i]))
{
if (p.outputType != -1)
{
warnPreviousOutputMethod(p.outputType);
}
p.outputType = FormatterListener::OUTPUT_METHOD_HTML;
}
else if(!compareNoCase("-DOM", argv[i]))
{
if (p.outputType != -1)
{
warnPreviousOutputMethod(p.outputType);
}
p.outputType = FormatterListener::OUTPUT_METHOD_DOM;
}
else if(!compareNoCase("-XST", argv[i]))
{
if (p.outputType != -1)
{
warnPreviousOutputMethod(p.outputType);
}
p.outputType = FormatterListener::OUTPUT_METHOD_DOM;
p.formatToSourceTree = true;
}
else if(!compareNoCase("-NULL", argv[i]))
{
p.formatToNull = true;
}
else if(!compareNoCase("-STRIPCDATA", argv[i]))
{
p.stripCData = true;
}
else if(!compareNoCase("-ESCAPECDATA", argv[i]))
{
p.escapeCData = true;
}
else if (!compareNoCase("-NH", argv[i]))
{
p.shouldWriteXMLHeader = false;
}
else if(!compareNoCase("-TT", argv[i]))
{
p.traceTemplates = true;
}
else if(!compareNoCase("-TG", argv[i]))
{
p.traceGenerationEvent = true;
}
else if(!compareNoCase("-TS", argv[i]))
{
p.traceSelectionEvent = true;
}
else if(!compareNoCase("-TTC", argv[i]))
{
p.traceTemplateChildren = true;
}
else if (!compareNoCase("-XD", argv[i]))
{
p.useDOM = true;
}
else if (!compareNoCase("-DE", argv[i]))
{
p.disableExtensions = true;
}
else if (!compareNoCase("-EN", argv[i]))
{
++i;
if(i < argc)
{
p.extentionsNamespace = argv[i];
if (strlen(p.extentionsNamespace) == 0)
{
fSuccess = false;
}
}
else
{
fSuccess = false;
}
}
else
{
cerr << endl << "Warning: Ignoring unknown option \"" << argv[i] << "\"." << endl << endl;
}
}
return fSuccess;
}
FormatterListener*
createFormatter(
int outputType,
bool shouldWriteXMLHeader,
bool stripCData,
bool escapeCData,
bool noIndent,
bool formatToNull,
bool formatToSourceTree,
PrintWriter& resultWriter,
int indentAmount,
const XalanDOMString& mimeEncoding,
const StylesheetRoot* stylesheet,
XMLParserLiaison& parserLiaison,
XalanSourceTreeParserLiaison& sourceTreeParserLiaison,
const PrefixResolver& prefixResolver,
const XalanDocument*& theResultDocument)
{
FormatterListener* formatter = 0;
if (formatToNull == true)
{
formatter = new FormatterToNull;
}
else if(FormatterListener::OUTPUT_METHOD_XML == outputType)
{
XalanDOMString version;
bool outputIndent = false;
XalanDOMString mediatype;
XalanDOMString doctypeSystem;
XalanDOMString doctypePublic;
XalanDOMString standalone;
if (stylesheet != 0)
{
version = stylesheet->m_version;
mediatype = stylesheet->m_mediatype;
doctypeSystem = stylesheet->getOutputDoctypeSystem();
doctypePublic = stylesheet->getOutputDoctypePublic();
standalone = stylesheet->m_standalone;
}
FormatterToXML* const fToXML =
new FormatterToXML(
resultWriter,
version,
outputIndent,
indentAmount,
mimeEncoding,
mediatype,
doctypeSystem,
doctypePublic,
true, // xmlDecl
standalone);
fToXML->setShouldWriteXMLHeader(shouldWriteXMLHeader);
fToXML->setStripCData(stripCData);
fToXML->setEscapeCData(escapeCData);
formatter = fToXML;
}
else if(FormatterListener::OUTPUT_METHOD_TEXT == outputType)
{
formatter = new FormatterToText(resultWriter, mimeEncoding);
}
else if(FormatterListener::OUTPUT_METHOD_HTML == outputType)
{
XalanDOMString version;
bool outputIndent = !noIndent;
XalanDOMString mediatype;
XalanDOMString doctypeSystem;
XalanDOMString doctypePublic;
XalanDOMString standalone;
if (stylesheet != 0)
{
version = stylesheet->m_version;
if (noIndent == false)
{
outputIndent = stylesheet->getOutputIndent();
}
mediatype = stylesheet->m_mediatype;
doctypeSystem = stylesheet->getOutputDoctypeSystem();
doctypePublic = stylesheet->getOutputDoctypePublic();
standalone = stylesheet->m_standalone;
}
FormatterToHTML* const fToHTML =
new FormatterToHTML(
resultWriter,
mimeEncoding,
mediatype,
doctypeSystem,
doctypePublic,
outputIndent,
indentAmount,
version,
standalone,
false); // xmlDecl
fToHTML->setStripCData(stripCData);
fToHTML->setPrefixResolver(&prefixResolver);
formatter = fToHTML;
}
else if(FormatterListener::OUTPUT_METHOD_DOM == outputType)
{
if (formatToSourceTree == true)
{
XalanSourceTreeDocument* theDocument =
sourceTreeParserLiaison.createXalanSourceTreeDocument();
assert(theDocument != 0);
theResultDocument = theDocument;
FormatterToSourceTree* const fToSourceTree =
new FormatterToSourceTree(theDocument);
fToSourceTree->setPrefixResolver(&prefixResolver);
formatter = fToSourceTree;
}
else
{
XalanDocument* const theDocument =
parserLiaison.createDOMFactory();
assert(theDocument != 0);
theResultDocument = theDocument;
FormatterToDOM* const fToDOM =
new FormatterToDOM(theDocument, 0);
fToDOM->setPrefixResolver(&prefixResolver);
formatter = fToDOM;
}
}
return formatter;
}
XalanOutputStream*
createOutputStream(const CmdLineParams& params)
{
if (params.outFileName == 0)
{
return new XalanStdOutputStream(cout);
}
else
{
return new XalanFileOutputStream(TranscodeFromLocalCodePage(params.outFileName));
}
}
TraceListener*
createTraceListener(
const CmdLineParams& params,
PrintWriter& diagnosticsWriter)
{
if (params.traceTemplates == true ||
params.traceTemplateChildren == true ||
params.traceGenerationEvent == true ||
params.traceSelectionEvent == true)
{
return new TraceListenerDefault(
diagnosticsWriter,
params.traceTemplates,
params.traceTemplateChildren,
params.traceGenerationEvent,
params.traceSelectionEvent);
}
else
{
return 0;
}
}
DOMSupport&
getDOMSupport(
XalanSourceTreeDOMSupport& theXalanSourceTreeDOMSupport,
XercesDOMSupport& theXercesDOMSupport,
const CmdLineParams& params)
{
if (params.useDOM == false)
{
return theXalanSourceTreeDOMSupport;
}
else
{
return theXercesDOMSupport;
}
}
XMLParserLiaison&
getParserLiaison(
XalanSourceTreeParserLiaison& theXalanSourceTreeParserLiaison,
XercesParserLiaison& theXercesParserLiaison,
const CmdLineParams& params)
{
if (params.useDOM == false)
{
return theXalanSourceTreeParserLiaison;
}
else
{
return theXercesParserLiaison;
}
}
void
installExtensions(
const CmdLineParams& params,
XSLTProcessorEnvSupportDefault& theXSLProcessorSupport)
{
XalanDOMString theXalanNamespace;
if (params.extentionsNamespace != 0)
{
theXalanNamespace = XalanDOMString(params.extentionsNamespace);
assert(length(theXalanNamespace) > 0);
}
else
{
theXalanNamespace = XALAN_STATIC_UCODE_STRING("http://xml.apache.org/xalan");
}
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("difference")),
FunctionDifference());
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("distinct")),
FunctionDistinct());
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("evaluate")),
FunctionEvaluate());
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("hasSameNodes")),
FunctionHasSameNodes());
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("intersection")),
FunctionIntersection());
theXSLProcessorSupport.installExternalFunctionLocal(
theXalanNamespace,
StaticStringToDOMString(XALAN_STATIC_UCODE_STRING("nodeset")),
FunctionNodeSet());
}
int
xsltMain(const CmdLineParams& params)
{
// Initialize the XSLT subsystem. This must stay in scope until
// we're done with the subsystem, since its destructor shuts down
// the subsystem.
XSLTInit theInit;
#if defined(XALAN_USE_ICU)
// Create an installer to install the substitute format-number() function.
FunctionICUFormatNumber::FunctionICUFormatNumberInstaller theInstaller;
#endif
const XalanDOMString mimeEncoding(XALAN_STATIC_UCODE_STRING("UTF-8"));
const XalanDOMString encoding(XALAN_STATIC_UCODE_STRING("UTF-8"));
/**
* The default diagnostic writer...
*/
XalanStdOutputStream theStdErr(cerr);
XalanOutputStreamPrintWriter diagnosticsWriter(theStdErr);
// Make sure that error reporting, which includes any TraceListener output
// does not throw exceptions when transcoding, since that could result in
// an exception being thrown will another exception is active. In particular,
// characters that the TraceListener writes might not be representable in the
// local code page.
theStdErr.setThrowTranscodeException(false);
// Initialize the XalanSourceTree subsystem. This must stay in scope until
// we're done with the subsystem, since its destructor shuts down the
// subsystem.
XalanSourceTreeInit theXalanSourceTreeInit;
XalanSourceTreeDOMSupport theXalanSourceTreeDOMSupport;
XalanSourceTreeParserLiaison theXalanSourceTreeParserLiaison(theXalanSourceTreeDOMSupport);
// Hookup the parser liaison instance to the support instance.
theXalanSourceTreeDOMSupport.setParserLiaison(&theXalanSourceTreeParserLiaison);
XercesDOMSupport theXercesDOMSupport;
XercesParserLiaison theXercesParserLiaison;
DOMSupport& theDOMSupport = getDOMSupport(
theXalanSourceTreeDOMSupport,
theXercesDOMSupport,
params);
XMLParserLiaison& xmlParserLiaison = getParserLiaison(
theXalanSourceTreeParserLiaison,
theXercesParserLiaison,
params);
XSLTProcessorEnvSupportDefault theXSLProcessorSupport;
if (params.disableExtensions == false)
{
installExtensions(params, theXSLProcessorSupport);
}
XObjectFactoryDefault theXObjectFactory;
XPathFactoryDefault theXPathFactory;
const XalanAutoPtr<TraceListener> theTraceListener(
createTraceListener(
params,
diagnosticsWriter));
XSLTEngineImpl processor(
xmlParserLiaison,
theXSLProcessorSupport,
theDOMSupport,
theXObjectFactory,
theXPathFactory);
theXSLProcessorSupport.setProcessor(&processor);
if (theTraceListener.get() != 0)
{
processor.setTraceSelects(params.traceSelectionEvent);
processor.addTraceListener(theTraceListener.get());
}
// Use a different factory type for the stylesheet. This is an optimization, since
// stylesheet XPath instances are built all at once and are deleted all at once when
// the stylesheet is destroyed.
XPathFactoryBlock theStylesheetXPathFactory;
StylesheetConstructionContextDefault theConstructionContext(
processor,
theStylesheetXPathFactory);
/*
* Set specified processor flags
*/
processor.setQuietConflictWarnings(params.setQuietConflictWarnings);
if (params.params.size() > 0)
{
StringPairVectorType::const_iterator it = params.params.begin();
for ( ; it != params.params.end(); ++it)
{
assert((*it).first != 0 && (*it).second != 0);
processor.setStylesheetParam(
XalanDOMString((*it).first),
XalanDOMString((*it).second));
}
}
/*
* Set specified parser flags
*/
if (params.indentAmount != 0)
{
xmlParserLiaison.setIndent(params.indentAmount);
}
xmlParserLiaison.setUseValidation(params.doValidation);
if (!params.setQuietMode)
{
processor.setDiagnosticsOutput(&diagnosticsWriter);
}
XalanDOMString xslFileName;
if(params.xslFileName != 0)
{
xslFileName = params.xslFileName;
}
const StylesheetRoot* stylesheet = 0;
if (!isEmpty(xslFileName))
{
stylesheet = processor.processStylesheet(xslFileName, theConstructionContext);
}
XalanAutoPtr<XalanOutputStream> outputFileStream(createOutputStream(params));
assert(outputFileStream.get() != 0);
XalanOutputStreamPrintWriter resultWriter(*outputFileStream.get());
const XalanDocument* theResultDocument = 0;
const XalanAutoPtr<FormatterListener> formatter(
createFormatter(
params.outputType,
params.shouldWriteXMLHeader,
params.stripCData,
params.escapeCData,
params.noIndent,
params.formatToNull,
params.formatToSourceTree,
resultWriter,
xmlParserLiaison.getIndent(),
mimeEncoding,
stylesheet,
xmlParserLiaison,
theXalanSourceTreeParserLiaison,
processor,
theResultDocument));
XSLTResultTarget rTreeTarget;
if(formatter.get() == 0)
{
rTreeTarget.setCharacterStream(&resultWriter);
}
else
{
rTreeTarget.setFormatterListener(formatter.get());
}
// Do the transformation...
XSLTInputSource theInputSource;
if (params.inFileName != 0)
{
theInputSource.setSystemId(c_wstr(XalanDOMString(params.inFileName)));
}
else
{
theInputSource.setStream(&cin);
cerr << "Reading input document from stdin..." << endl;
}
StylesheetExecutionContextDefault theExecutionContext(processor,
theXSLProcessorSupport,
theDOMSupport,
theXObjectFactory);
#if defined(XALAN_USE_ICU)
ICUBridgeCollationCompareFunctor theICUFunctor;
theExecutionContext.installCollationCompareFunctor(&theICUFunctor);
#endif
if (params.useDOM == false)
{
theXalanSourceTreeParserLiaison.setExecutionContext(theExecutionContext);
}
else
{
theXercesParserLiaison.setExecutionContext(theExecutionContext);
}
if (stylesheet == 0)
{
// No stylesheet, so our only hope is that the xml file has
// PI with the stylesheet...
// Dummy input source...
XSLTInputSource theStylesheetSource;
processor.process(
theInputSource,
theStylesheetSource,
rTreeTarget,
theConstructionContext,
theExecutionContext);
}
else
{
theExecutionContext.setStylesheetRoot(stylesheet);
processor.process(
theInputSource,
rTreeTarget,
theExecutionContext);
}
if (params.outputType == FormatterListener::OUTPUT_METHOD_DOM)
{
// Output is to DOM, so we have to format to XML to
// produce output...
assert(rTreeTarget.getFormatterListener() != 0 &&
rTreeTarget.getFormatterListener()->getOutputFormat() ==
FormatterListener::OUTPUT_METHOD_DOM);
if (theResultDocument == 0)
{
cerr << endl << "Error: No document to format!!!" << endl;
}
else
{
// Create a FormaterToXML with the required output
// options...
const XalanAutoPtr<FormatterListener> formatter(
createFormatter(
FormatterListener::OUTPUT_METHOD_XML,
params.shouldWriteXMLHeader,
params.stripCData,
params.escapeCData,
params.noIndent,
false,
false,
resultWriter,
xmlParserLiaison.getIndent(),
mimeEncoding,
stylesheet,
xmlParserLiaison,
theXalanSourceTreeParserLiaison,
processor,
theResultDocument));
// Create a FormatterTreeWalker with the the
// new formatter...
FormatterTreeWalker theTreeWalker(*formatter.get());
// Walk the document and produce the XML...
theTreeWalker.traverse(theResultDocument);
}
}
theExecutionContext.reset();
theConstructionContext.reset();
theStylesheetXPathFactory.reset();
processor.reset();
theXPathFactory.reset();
theXObjectFactory.reset();
theXSLProcessorSupport.reset();
theDOMSupport.reset();
xmlParserLiaison.reset();
return 0;
}
int
main(
int argc,
const char* argv[])
{
#if !defined(XALAN_USE_ICU) && !defined(NDEBUG) && defined(_MSC_VER)
_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif
#if defined(XALAN_VQ_SPECIAL_TRACE)
QuantifyStopRecordingData();
#endif
int theResult = 0;
CmdLineParams theParams;
/*
* Get command line arguments
*/
if (getArgs(argc, argv, theParams) == false)
{
printArgOptions();
}
else if (theParams.versionOnly == true)
{
cout << endl
<< "TestXSLT version 1.3 (Xalan C++ version 1.3)"
<< endl;
}
else
{
XMLPlatformUtils::Initialize();
try
{
theResult = xsltMain(theParams);
}
catch (const XSLException& e)
{
cout << "\nXSLException ";
cout << "Type is: " << e.getType() << endl;
cout << "Message is: " << e.getMessage() << " (";
const XalanDOMString& theURI = e.getURI();
if (length(theURI) != 0)
{
cout << theURI;
}
else
{
cout << "Unknown URI";
}
cout << ", line "
<< e.getLineNumber()
<< ", column "
<< e.getColumnNumber()
<< ")"
<< endl;
theResult = -1;
}
catch (const SAXParseException& e)
{
cout << "\nSAXParseException ";
cout << "Message is: " << e.getMessage() << " (";
const XMLCh* const theSystemID = e.getSystemId();
if (theSystemID != 0)
{
cout << XalanDOMString(theSystemID);
}
else
{
cout << "Unknown system ID";
}
cout << ", line "
<< e.getLineNumber()
<< ", column "
<< e.getColumnNumber()
<< ")"
<< endl;
theResult = -2;
}
catch (const SAXException& e)
{
cout << "\nSAXException ";
cout << "Message is: " << e.getMessage() << endl;
theResult = -2;
}
catch (const XMLException& e)
{
cout << "\nXMLException ";
cout << "Type is: " << e.getType() << endl;
cout << "Message is: " << e.getMessage() << endl;
theResult = -3;
}
catch(const XalanDOMException& e)
{
cout << endl
<< "XalanDOMException caught. The code is "
<< int(e.getExceptionCode())
<< "."
<< endl;
theResult = -4;
}
catch (...)
{
cout << "\nUnhandled Exception\n";
theResult = -5;
}
#if !defined(NDEBUG)
const size_t theInstanceCount =
XalanNode::getInstanceCount();
if (theInstanceCount > 0)
{
cout << "There are "
<< theInstanceCount
<< " XalanNode instances still alive!"
<< endl
<< endl
<< "A dump of these instances follows..."
<< endl
<< endl;
typedef vector<XalanNode*> NodeVectorType;
NodeVectorType theNodes(theInstanceCount, NodeVectorType::value_type(0));
XalanNode::getLiveInstances(&*theNodes.begin());
for(size_t i = 0; i < theInstanceCount; ++i)
{
const XalanNode* const theInstance = theNodes[i];
if(theInstance == 0)
{
cout << "No instance information is available..."
<< endl;
}
else
{
cout << "("
<< hex
<< theInstance
<< ") Node name: \""
<< theInstance->getNodeName()
<< "\" Node value: \""
<< theInstance->getNodeValue()
<< "\""
#if defined(XALAN_RTTI_AVAILABLE) && !defined(XALAN_NO_TYPEINFO)
<< " Type: \""
<< typeid(*theInstance).name()
<< "\""
#endif
<< endl
<< endl;
}
}
}
#endif
XMLPlatformUtils::Terminate();
}
return theResult;
}