In this chapter, we will discuss different aspects common to each process of transformation (XML to GRP, GRP to SVG, and XML to SVG) that you should be aware of when programming if you don't want to wonder for a long time why some thing happened.
When you transform a document, many messages may be displayed in the console :
These messages are displayed to tell you what is going on. Here are some progress messages examples :
Applying XSL transformations to file ../XML/XML/ex1.cd
Parsing file ../XML/XML/definitionsCD.def
Generating GRP file ../XML/XML/ex1.cd.grp
Creating SVG document
Generating SVG file ../XML/XML/ex1.cd.svg
These messages are displayed on the standard output stream.
These messages are displayed to tell you that something wrong happened during the process of transformation. The cause of these messages do not prevent the process of transformation from carrying on. Here are some warning messages examples :
Warning: vertical box whose id is 'vbox' contains 2 boxes (id 'tbox2' & 'tbox1') with different widths (95.0 & 109.0)
BoxLink not added: Box whose id is 'tbox1' doesn't exist.
Warning : a reference points to an incorrect id : 'N2f83581'
These messages are displayed on the error output stream.
These messages are displayed to tell you that a fatal error happened during the process of transformation. The cause of these messages prevent the process of transformation from carrying on. Here is some error message example :
file:///D:/editor/XML/XML/CDtoGRP.xsl; Line 243; Column 17
XSL Error: Could not parse CDtoGRP.xsl document!
XSL Error: SAX Exception
Exception in thread "main" org.apache.xalan.xslt.XSLProcessorException: The end-tag for element type "xsl:stylesheet" must end with a '>' delimiter.
at org.apache.xalan.xslt.XSLTEngineImpl.error(XSLTEngineImpl.java:1753)
at org.apache.xalan.xslt.XSLTEngineImpl.processStylesheet(XSLTEngineImpl.java:813)
at org.apache.xalan.xslt.XSLTEngineImpl.process(XSLTEngineImpl.java:647)
at fr.loria.taxi.transformer.Transformer.createDocumentGRPFromXSL(Transformer.java:118)
at fr.loria.taxi.transformer.Transformer.createDocumentGRPFromXSL(Transformer.java:95)
at fr.loria.taxi.transformer.TransformerXMLToGRP.process(TransformerXMLToGRP.java:17)
at fr.loria.taxi.transformer.TransformerXMLToGRP.main(TransformerXMLToGRP.java:34)
These messages, thrown by the XML parser and serializer, are displayed on the error output stream.
If you don't want these messages to appear on the console, the only thing you have to
do is to redirect the standard output stream and/or the error output stream. To do so,
just use the Java methods System.setOut(PrintStream out) and
System.setErr(PrintStream err). All you have to provide as parameter
for these methods is an object that inherits java.io.PrintStream.
Note : this is exactly what is done with TAXI. Streams are redirected to
write to a javax.swing.text.StyledDocument. The object passed to methods
System.setOut(PrintStream out) and System.setErr(PrintStream err)
is an editor.io.DocumentPrintStream.
The default behavior of the XML parser used by the process of transformation is to stop the application as soon as a parsing error occurs.
Save the following code under editor/test/ParsingErrorTest.java :
import fr.loria.taxi.transformer.TransformerXMLToSVG;
import fr.loria.taxi.transformer.util.Parameters;
import fr.loria.taxi.transformer.util.XMLToSVGParameters;
public class ParsingErrorTest {
/**
* This method prepares the parameters needed by the process of transformation. If any
* error happens, we display an error message and leave the application.
*
* @return The list of parameters as an XMLToSVGParameters object.
*/
public static XMLToSVGParameters getParameters() {
XMLToSVGParameters parameters = null;
try {
// The array containing the parameters
String[] args = new String[10];
// GRP document to transform
args[0] = Parameters.PARAMETER_SIGN + Parameters.XML_IN; // -xml_in
args[1] = "foo.xml";
// XSLT stylesheet to use
args[2] = Parameters.PARAMETER_SIGN + Parameters.XSL; // -xsl
args[3] = "../XML/Generic/genericHorizontal.xsl";
// GRP DTD
args[4] = Parameters.PARAMETER_SIGN + Parameters.GRP_DTD; // -grp_dtd
args[5] = "../grp.dtd";
// Definitions document to use
args[6] = Parameters.PARAMETER_SIGN + Parameters.DEFS; // -defs
args[7] = "../XML/Generic/generic.def";
// SVG DTD
args[8] = Parameters.PARAMETER_SIGN + Parameters.SVG_DTD; // -svg_dtd
args[9] = "../svg.dtd";
parameters = new XMLToSVGParameters(args);
} catch (Exception e) {
// We report any error that might happen with the parameters and leave the application
System.err.println("-- Something wrong with the parameters --");
System.err.println(e.getMessage());
System.exit(1);
}
return parameters;
}
/**
* Main method.
*/
public static void main(String[] args) {
try {
// Prepares the list of parameters
XMLToSVGParameters parameters = getParameters();
// Creates the Transformer and calls the process() method that operates the process
// of transformation
TransformerXMLToSVG transformer = new TransformerXMLToSVG(parameters);
fr.loria.taxi.transformer.process();
// We force the exit of the application because an instance of an AWT object has been
// created during the process of transformation, thus, the system doesn't relinquish
// control as it assumes that some GUI is running.
System.exit(0);
} catch (Exception e) {
// We report any error that might happen during the process of transformation
System.err.println("-- Something wrong happened during the transformation --");
System.err.println(e.getMessage());
}
System.out.println("Finished");
}
}
Open a console, go to directory editor/test and compile
ParsingErrorTest.java with the following command :
javac -classpath ../lib/taxi.jar ParsingErrorTest.java
Note : classes and sources are usually not saved in the same directory. This is not the case with the previous command line used for compiling. I chose to do that to focus only on the process of transformation and use the minimum number of necessary options on the command line.
Most of the code is taken back from examples of the previous chapter. If you didn't read it, please refer to it for explanations about most of lines of code of the example above.
In method getParameters(), we specify that we want to transform the XML
document foo.xml that does not exist.
In method main(String[] args), we apply transformation, report any
Exception that might occur during the process of transformation, and then
write the message Finished. This is at least what we want to happen.
Run the example with this command (depending on the OS you run it, you will not use the same classpath separator) :
java -classpath ../lib/taxi.jar;. ParsingErrorTest (under Windows)
java -classpath ../lib/taxi.jar:. ParsingErrorTest (under other OS)
You get the following output :
Applying XSL transformations to file foo.xml
[Fatal Error] :0:0: File "file:///D:/editor/test/foo.xml" not found.
The XML parser didn't find the document foo.xml. Of course, this document
doesn't exist. The error has been reported and the application has been stopped !
Thus, we have never executed the code that handles Exception that might happen
during the process of transformation, and so never the code that displays Finished.
Why ? Because, by default, the XML parser used by the process of transformation stops the
application if a parsing error occurs, like transforming an XML document that does not exist.
Modify editor/test/ParsingErrorTest.java (changes are in bold) :
import fr.loria.taxi.transformer.TransformerXMLToSVG;
import fr.loria.taxi.transformer.util.Parameters;
import fr.loria.taxi.transformer.util.XMLToSVGParameters;
public class ParsingErrorTest {
/**
* This method prepares the parameters needed by the process of transformation. If any
* error happens, we display an error message and leave the application.
*
* @return The list of parameters as an XMLToSVGParameters object.
*/
public static XMLToSVGParameters getParameters() {
XMLToSVGParameters parameters = null;
try {
// The array containing the parameters
String[] args = new String[10];
// GRP document to transform
args[0] = Parameters.PARAMETER_SIGN + Parameters.XML_IN; // -xml_in
args[1] = "foo.xml";
// XSLT stylesheet to use
args[2] = Parameters.PARAMETER_SIGN + Parameters.XSL; // -xsl
args[3] = "../XML/Generic/genericHorizontal.xsl";
// GRP DTD
args[4] = Parameters.PARAMETER_SIGN + Parameters.GRP_DTD; // -grp_dtd
args[5] = "../grp.dtd";
// Definitions document to use
args[6] = Parameters.PARAMETER_SIGN + Parameters.DEFS; // -defs
args[7] = "../XML/Generic/generic.def";
// SVG DTD
args[8] = Parameters.PARAMETER_SIGN + Parameters.SVG_DTD; // -svg_dtd
args[9] = "../svg.dtd";
parameters = new XMLToSVGParameters(args);
} catch (Exception e) {
// We report any error that might happen with the parameters and leave the application
System.err.println("-- Something wrong with the parameters --");
System.err.println(e.getMessage());
System.exit(1);
}
return parameters;
}
/**
* Main method.
*/
public static void main(String[] args) {
try {
// Prepares the list of parameters
XMLToSVGParameters parameters = getParameters();
// Creates the Transformer and calls the process() method that operates the process
// of transformation
TransformerXMLToSVG transformer = new TransformerXMLToSVG(parameters);
transformer.setStopAfterParsingError(false);
fr.loria.taxi.transformer.process();
// We force the exit of the application because an instance of an AWT object has been
// created during the process of transformation, thus, the system doesn't relinquish
// control as it assumes that some GUI is running.
System.exit(0);
} catch (Exception e) {
// We report any error that might happen during the process of transformation
System.err.println("-- Something wrong happened during the transformation --");
System.err.println(e.getMessage());
}
System.out.println("Finished");
}
}
Open a console, go to directory editor/test and compile
ParsingErrorTest.java with the following command :
javac -classpath ../lib/taxi.jar ParsingErrorTest.java
We just add the line transformer.setStopAfterParsingError(false); to ask
the Transformer to tell the XML parser not to stop the application if a parsing error occurs
during the process of transformation.
Run the example with this command (depending on the OS you run it, you will not use the same classpath separator) :
java -classpath ../lib/taxi.jar;. ParsingErrorTest (under Windows)
java -classpath ../lib/taxi.jar:. ParsingErrorTest (under other OS)
You get the following output :
Applying XSL transformations to file foo.xml
[Fatal Error] :0:0: File "file:///D:/editor/test/foo.xml" not found.
-- Something wrong happened during the transformation --
Stopping after fatal error: File "file:///D:/editor/test/foo.xml" not found.
Finished
As in the previous example, the XML parser didn't find the document foo.xml.
The error has been reported, but this time, the application has not been stopped !
Thus, we have executed the code that handles Exception that might happen
during the process of transformation, and so the code that displays Finished.