Command line interface to transform an XML document according to
the instructions found in an XSL stylesheet.
The Process class provides basic functionality for
performing transformations from the command line. To see a
list of arguments supported, call with zero arguments.
To set stylesheet parameters from the command line, use
-PARAM name expression
. If you want to set the
parameter to a string value, simply pass the string value
as-is, and it will be interpreted as a string. (Note: if
the value has spaces in it, you may need to quote it depending
on your shell environment).
boolean doStackDumpOnError = false;
boolean setQuietMode = false;
boolean doDiag = false;
/**
* The default diagnostic writer...
*/
java.io.PrintWriter diagnosticsWriter = new PrintWriter(System.err, true);
java.io.PrintWriter dumpWriter = diagnosticsWriter;
ResourceBundle resbundle =
(XSLMessages.loadResourceBundle(
com.sun.org.apache.xml.internal.utils.res.XResourceBundle.ERROR_RESOURCES));
String flavor = "s2s";
if (argv.length < 1)
{
printArgOptions(resbundle);
}
else
{
// since xsltc is the default transformer
boolean useXSLTC = true;
for (int i = 0; i < argv.length; i++)
{
if ("-XSLTC".equalsIgnoreCase(argv[i]))
{
useXSLTC = true;
}
}
TransformerFactory tfactory;
// Since xsltc is the default transformer
String key = "javax.xml.transform.TransformerFactory";
String value = "com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl";
Properties props = System.getProperties();
props.put(key, value);
System.setProperties(props);
try
{
tfactory = TransformerFactory.newInstance();
}
catch (TransformerFactoryConfigurationError pfe)
{
pfe.printStackTrace(dumpWriter);
diagnosticsWriter.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
tfactory = null; // shut up compiler
doExit(-1);
}
boolean formatOutput = false;
boolean useSourceLocation = false;
String inFileName = null;
String outFileName = null;
String dumpFileName = null;
String xslFileName = null;
String treedumpFileName = null;
String outputType = null;
String media = null;
Vector params = new Vector();
boolean quietConflictWarnings = false;
URIResolver uriResolver = null;
EntityResolver entityResolver = null;
ContentHandler contentHandler = null;
int recursionLimit=-1;
for (int i = 0; i < argv.length; i++)
{
if ("-XSLTC".equalsIgnoreCase(argv[i]))
{
// The -XSLTC option has been processed.
}
else if ("-INDENT".equalsIgnoreCase(argv[i]))
{
int indentAmount;
if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-"))
{
indentAmount = Integer.parseInt(argv[++i]);
}
else
{
indentAmount = 0;
}
// TBD:
// xmlProcessorLiaison.setIndent(indentAmount);
}
else if ("-IN".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
inFileName = argv[++i];
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-IN" })); //"Missing argument for);
}
else if ("-MEDIA".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length)
media = argv[++i];
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-MEDIA" })); //"Missing argument for);
}
else if ("-OUT".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
outFileName = argv[++i];
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-OUT" })); //"Missing argument for);
}
else if ("-XSL".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
xslFileName = argv[++i];
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-XSL" })); //"Missing argument for);
}
else if ("-FLAVOR".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length)
{
flavor = argv[++i];
}
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-FLAVOR" })); //"Missing argument for);
}
else if ("-PARAM".equalsIgnoreCase(argv[i]))
{
if (i + 2 < argv.length)
{
String name = argv[++i];
params.addElement(name);
String expression = argv[++i];
params.addElement(expression);
}
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-PARAM" })); //"Missing argument for);
}
else if ("-E".equalsIgnoreCase(argv[i]))
{
// TBD:
// xmlProcessorLiaison.setShouldExpandEntityRefs(false);
}
else if ("-V".equalsIgnoreCase(argv[i]))
{
diagnosticsWriter.println(resbundle.getString("version") //">>>>>>> Xalan Version "
+ Version.getVersion() + ", " +
resbundle.getString("version2")); // "<<<<<<<");
}
else if ("-Q".equalsIgnoreCase(argv[i]))
{
setQuietMode = true;
}
else if ("-DIAG".equalsIgnoreCase(argv[i]))
{
doDiag = true;
}
else if ("-XML".equalsIgnoreCase(argv[i]))
{
outputType = "xml";
}
else if ("-TEXT".equalsIgnoreCase(argv[i]))
{
outputType = "text";
}
else if ("-HTML".equalsIgnoreCase(argv[i]))
{
outputType = "html";
}
else if ("-EDUMP".equalsIgnoreCase(argv[i]))
{
doStackDumpOnError = true;
if (((i + 1) < argv.length) && (argv[i + 1].charAt(0) != '-"))
{
dumpFileName = argv[++i];
}
}
else if ("-URIRESOLVER".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length)
{
try
{
uriResolver = (URIResolver) ObjectFactory.newInstance(
argv[++i], ObjectFactory.findClassLoader(), true);
tfactory.setURIResolver(uriResolver);
}
catch (ObjectFactory.ConfigurationError cnfe)
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
new Object[]{ "-URIResolver" }));
doExit(-1);
}
}
else
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-URIResolver" })); //"Missing argument for);
doExit(-1);
}
}
else if ("-ENTITYRESOLVER".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length)
{
try
{
entityResolver = (EntityResolver) ObjectFactory.newInstance(
argv[++i], ObjectFactory.findClassLoader(), true);
}
catch (ObjectFactory.ConfigurationError cnfe)
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
new Object[]{ "-EntityResolver" }));
doExit(-1);
}
}
else
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-EntityResolver" })); //"Missing argument for);
doExit(-1);
}
}
else if ("-CONTENTHANDLER".equalsIgnoreCase(argv[i]))
{
if (i + 1 < argv.length)
{
try
{
contentHandler = (ContentHandler) ObjectFactory.newInstance(
argv[++i], ObjectFactory.findClassLoader(), true);
}
catch (ObjectFactory.ConfigurationError cnfe)
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_CLASS_NOT_FOUND_FOR_OPTION,
new Object[]{ "-ContentHandler" }));
doExit(-1);
}
}
else
{
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-ContentHandler" })); //"Missing argument for);
doExit(-1);
}
}
// Generate the translet class and optionally specify the name
// of the translet class.
else if ("-XO".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
if (i + 1 < argv.length && argv[i+1].charAt(0) != '-")
{
tfactory.setAttribute("generate-translet", "true");
tfactory.setAttribute("translet-name", argv[++i]);
}
else
tfactory.setAttribute("generate-translet", "true");
}
else
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
i++;
printInvalidXalanOption("-XO");
}
}
// Specify the destination directory for the translet classes.
else if ("-XD".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
if (i + 1 < argv.length && argv[i+1].charAt(0) != '-")
tfactory.setAttribute("destination-directory", argv[++i]);
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-XD" })); //"Missing argument for);
}
else
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
i++;
printInvalidXalanOption("-XD");
}
}
// Specify the jar file name which the translet classes are packaged into.
else if ("-XJ".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
if (i + 1 < argv.length && argv[i+1].charAt(0) != '-")
{
tfactory.setAttribute("generate-translet", "true");
tfactory.setAttribute("jar-name", argv[++i]);
}
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-XJ" })); //"Missing argument for);
}
else
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
i++;
printInvalidXalanOption("-XJ");
}
}
// Specify the package name prefix for the generated translet classes.
else if ("-XP".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
if (i + 1 < argv.length && argv[i+1].charAt(0) != '-")
tfactory.setAttribute("package-name", argv[++i]);
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_MISSING_ARG_FOR_OPTION,
new Object[]{ "-XP" })); //"Missing argument for);
}
else
{
if (i + 1 < argv.length && argv[i + 1].charAt(0) != '-")
i++;
printInvalidXalanOption("-XP");
}
}
// Enable template inlining.
else if ("-XN".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
tfactory.setAttribute("enable-inlining", "true");
}
else
printInvalidXalanOption("-XN");
}
// Turns on additional debugging message output
else if ("-XX".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
tfactory.setAttribute("debug", "true");
}
else
printInvalidXalanOption("-XX");
}
// Create the Transformer from the translet if the translet class is newer
// than the stylesheet.
else if ("-XT".equalsIgnoreCase(argv[i]))
{
if (useXSLTC)
{
tfactory.setAttribute("auto-translet", "true");
}
else
printInvalidXalanOption("-XT");
}
else
System.err.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_INVALID_OPTION, new Object[]{ argv[i] })); //"Invalid argument:);
}
// Print usage instructions if no xml and xsl file is specified in the command line
if (inFileName == null && xslFileName == null)
{
System.err.println(resbundle.getString("xslProc_no_input"));
doExit(-1);
}
// Note that there are usage cases for calling us without a -IN arg
// The main XSL transformation occurs here!
try
{
long start = System.currentTimeMillis();
if (null != dumpFileName)
{
dumpWriter = new PrintWriter(new FileWriter(dumpFileName));
}
Templates stylesheet = null;
if (null != xslFileName)
{
if (flavor.equals("d2d"))
{
// Parse in the xml data into a DOM
DocumentBuilderFactory dfactory =
DocumentBuilderFactory.newInstance();
dfactory.setNamespaceAware(true);
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
Node xslDOM = docBuilder.parse(new InputSource(xslFileName));
stylesheet = tfactory.newTemplates(new DOMSource(xslDOM,
xslFileName));
}
else
{
stylesheet = tfactory.newTemplates(new StreamSource(xslFileName));
}
}
PrintWriter resultWriter;
StreamResult strResult;
if (null != outFileName)
{
strResult = new StreamResult(new FileOutputStream(outFileName));
// One possible improvement might be to ensure this is
// a valid URI before setting the systemId, but that
// might have subtle changes that pre-existing users
// might notice; we can think about that later -sc r1.46
strResult.setSystemId(outFileName);
}
else
{
strResult = new StreamResult(System.out);
// We used to default to incremental mode in this case.
// We've since decided that since the -INCREMENTAL switch is
// available, that default is probably not necessary nor
// necessarily a good idea.
}
SAXTransformerFactory stf = (SAXTransformerFactory) tfactory;
// Did they pass in a stylesheet, or should we get it from the
// document?
if (null == stylesheet)
{
Source source =
stf.getAssociatedStylesheet(new StreamSource(inFileName), media,
null, null);
if (null != source)
stylesheet = tfactory.newTemplates(source);
else
{
if (null != media)
throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_IN_MEDIA, new Object[]{inFileName, media})); //"No stylesheet found in: "
// + inFileName + ", media="
// + media);
else
throw new TransformerException(XSLMessages.createMessage(XSLTErrorResources.ER_NO_STYLESHEET_PI, new Object[]{inFileName})); //"No xml-stylesheet PI found in: "
//+ inFileName);
}
}
if (null != stylesheet)
{
Transformer transformer = flavor.equals("th") ? null : stylesheet.newTransformer();
// Override the output format?
if (null != outputType)
{
transformer.setOutputProperty(OutputKeys.METHOD, outputType);
}
int nParams = params.size();
for (int i = 0; i < nParams; i += 2)
{
transformer.setParameter((String) params.elementAt(i),
(String) params.elementAt(i + 1));
}
if (uriResolver != null)
transformer.setURIResolver(uriResolver);
if (null != inFileName)
{
if (flavor.equals("d2d"))
{
// Parse in the xml data into a DOM
DocumentBuilderFactory dfactory =
DocumentBuilderFactory.newInstance();
dfactory.setCoalescing(true);
dfactory.setNamespaceAware(true);
DocumentBuilder docBuilder = dfactory.newDocumentBuilder();
if (entityResolver != null)
docBuilder.setEntityResolver(entityResolver);
Node xmlDoc = docBuilder.parse(new InputSource(inFileName));
Document doc = docBuilder.newDocument();
org.w3c.dom.DocumentFragment outNode =
doc.createDocumentFragment();
transformer.transform(new DOMSource(xmlDoc, inFileName),
new DOMResult(outNode));
// Now serialize output to disk with identity transformer
Transformer serializer = stf.newTransformer();
Properties serializationProps =
stylesheet.getOutputProperties();
serializer.setOutputProperties(serializationProps);
if (contentHandler != null)
{
SAXResult result = new SAXResult(contentHandler);
serializer.transform(new DOMSource(outNode), result);
}
else
serializer.transform(new DOMSource(outNode), strResult);
}
else if (flavor.equals("th"))
{
for (int i = 0; i < 1; i++) // Loop for diagnosing bugs with inconsistent behavior
{
// System.out.println("Testing the TransformerHandler...");
// ===============
XMLReader reader = null;
// Use JAXP1.1 ( if possible )
try
{
javax.xml.parsers.SAXParserFactory factory =
javax.xml.parsers.SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
javax.xml.parsers.SAXParser jaxpParser =
factory.newSAXParser();
reader = jaxpParser.getXMLReader();
}
catch (javax.xml.parsers.ParserConfigurationException ex)
{
throw new org.xml.sax.SAXException(ex);
}
catch (javax.xml.parsers.FactoryConfigurationError ex1)
{
throw new org.xml.sax.SAXException(ex1.toString());
}
catch (NoSuchMethodError ex2){}
catch (AbstractMethodError ame){}
if (null == reader)
{
reader = XMLReaderFactory.createXMLReader();
}
TransformerHandler th = stf.newTransformerHandler(stylesheet);
reader.setContentHandler(th);
reader.setDTDHandler(th);
if(th instanceof org.xml.sax.ErrorHandler)
reader.setErrorHandler((org.xml.sax.ErrorHandler)th);
try
{
reader.setProperty(
"http://xml.org/sax/properties/lexical-handler", th);
}
catch (org.xml.sax.SAXNotRecognizedException e){}
catch (org.xml.sax.SAXNotSupportedException e){}
try
{
reader.setFeature("http://xml.org/sax/features/namespace-prefixes",
true);
} catch (org.xml.sax.SAXException se) {}
th.setResult(strResult);
reader.parse(new InputSource(inFileName));
}
}
else
{
if (entityResolver != null)
{
XMLReader reader = null;
// Use JAXP1.1 ( if possible )
try
{
javax.xml.parsers.SAXParserFactory factory =
javax.xml.parsers.SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
javax.xml.parsers.SAXParser jaxpParser =
factory.newSAXParser();
reader = jaxpParser.getXMLReader();
}
catch (javax.xml.parsers.ParserConfigurationException ex)
{
throw new org.xml.sax.SAXException(ex);
}
catch (javax.xml.parsers.FactoryConfigurationError ex1)
{
throw new org.xml.sax.SAXException(ex1.toString());
}
catch (NoSuchMethodError ex2){}
catch (AbstractMethodError ame){}
if (null == reader)
{
reader = XMLReaderFactory.createXMLReader();
}
reader.setEntityResolver(entityResolver);
if (contentHandler != null)
{
SAXResult result = new SAXResult(contentHandler);
transformer.transform(
new SAXSource(reader, new InputSource(inFileName)),
result);
}
else
{
transformer.transform(
new SAXSource(reader, new InputSource(inFileName)),
strResult);
}
}
else if (contentHandler != null)
{
SAXResult result = new SAXResult(contentHandler);
transformer.transform(new StreamSource(inFileName), result);
}
else
{
transformer.transform(new StreamSource(inFileName),
strResult);
}
}
}
else
{
StringReader reader =
new StringReader("<?xml version=\"1.0\"?> <doc/>");
transformer.transform(new StreamSource(reader), strResult);
}
}
else
{
diagnosticsWriter.println(
XSLMessages.createMessage(
XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
doExit(-1);
}
// close output streams
if (null != outFileName && strResult!=null)
{
java.io.OutputStream out = strResult.getOutputStream();
java.io.Writer writer = strResult.getWriter();
try
{
if (out != null) out.close();
if (writer != null) writer.close();
}
catch(java.io.IOException ie) {}
}
long stop = System.currentTimeMillis();
long millisecondsDuration = stop - start;
if (doDiag)
{
Object[] msgArgs = new Object[]{ inFileName, xslFileName, new Long(millisecondsDuration) };
String msg = XSLMessages.createMessage("diagTiming", msgArgs);
diagnosticsWriter.println('\n");
diagnosticsWriter.println(msg);
}
}
catch (Throwable throwable)
{
while (throwable
instanceof com.sun.org.apache.xml.internal.utils.WrappedRuntimeException)
{
throwable =
((com.sun.org.apache.xml.internal.utils.WrappedRuntimeException) throwable).getException();
}
if ((throwable instanceof NullPointerException)
|| (throwable instanceof ClassCastException))
doStackDumpOnError = true;
diagnosticsWriter.println();
if (doStackDumpOnError)
throwable.printStackTrace(dumpWriter);
else
{
DefaultErrorHandler.printLocation(diagnosticsWriter, throwable);
diagnosticsWriter.println(
XSLMessages.createMessage(XSLTErrorResources.ER_XSLT_ERROR, null)
+ " (" + throwable.getClass().getName() + "): "
+ throwable.getMessage());
}
// diagnosticsWriter.println(XSLMessages.createMessage(XSLTErrorResources.ER_NOT_SUCCESSFUL, null)); //"XSL Process was not successful.");
if (null != dumpFileName)
{
dumpWriter.close();
}
doExit(-1);
}
if (null != dumpFileName)
{
dumpWriter.close();
}
if (null != diagnosticsWriter)
{
// diagnosticsWriter.close();
}
}