|
 |
 |
 |
 |
I'm having a problem running Xalan-Java
on the JDK 1.4. |
 |
 |
 |
 |
|
|
The Sun JDK 1.4 is packaged with an old version (2.2D11)
of Xalan-Java. The JDK 1.4 will attempt to use this version instead
of any on the classpath. Unfortunately, this causes problems when
attempting to use a newer version of Xalan-Java with the Sun JDK
1.4.
You can always determine which version of Xalan-Java you
are running by using the EnvironmentCheck class or by
using the xalan:checkEnvironment extension function. It is highly
recommended that you use this method to verify the version of
Xalan-Java you are running, especially before opening a bug
report.
There are several ways to use a later version of
Xalan-Java and override the one packaged with the JDK:
- For the SUN JDK 1.4, use the Endorsed Standards Override Mechanism. Place the
xalan.jar, xercesImpl.jar, and xml-apis.jar in the
<java-home>\lib\endorsed directory, where <java-home>
is where the runtime software is installed.
- Use the -Xbootclasspath java commandline option to
prepend the new xalan.jar, xercesImpl.jar, and xml-apis.jar to the
boot class path. When running Xalan-Java:
java
-Xbootclasspath/p:<path>
org.apache.xalan.xslt.Process
where <path> is a colon seperated lists of the paths to the
files xalan.jar, xercesImpl.jar, and xml-apis.jar (e.g.
bin/xalan.jar:bin/xercesImpl.jar:bin/xml-apis.jar) containing the
new-version of Xalan-Java.
The following methods do not work:
- Using the CLASSPATH environment variable or using
-classpath to place the new classes in the classpath.
- Using the -jar option to explicitly execute the classes
inside the new jar files.
|
 |
 |
 |
 |
How do I get line numbers for errors in
the XML or XSL input when I am performing a
transformation? |
 |
 |
 |
 |
|
|
Use or mimic the command-line processor (
org.apache.xalan.xslt.Process).
A
TransformerException generally wraps another exception, often a
SAXParseException. The command-line processor uses the static
org.apache.xml.utils.DefaultErrorHandler printLocation() method
to chase down the exception cause and get a
SourceLocatorthat can usually report line and column
number.
Suppose you wanted to modify the ValidateXMLInput sample
in the samples/Validate subdirectory to include line and column
numbers . All you need to do is call
DefaultErrorHandler.printLocation() in the the Handler internal
class error() and warning() methods. For example,
replace
 |
 |
 |
 |
public void error (SAXParseException spe)
throws SAXException
{
System.out.println("SAXParseException error: " + spe.getMessage());
}
|
 |
 |
 |
 |
with
 |
 |
 |
 |
public void error (SAXParseException spe)
throws SAXException
{
PrintWriter pw = new PrintWriter(System.out, true);
org.apache.xml.utils.DefaultErrorHandler.printLocation(pw, spe);
pw.println("SAXParseException error: " + spe.getMessage());
}
|
 |
 |
 |
 |
You can also replicate code from the printLocation()
method to obtain a SourceLocator, and then use the SourceLocator
getLineNumber() and getColumnNumber() methods. The
getRootSourceLocator() method below returns a
SourceLocator.
 |
 |
 |
 |
import javax.xml.transform.SourceLocator;
import javax.xml.transform.TransformerException;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.apache.xml.utils.SAXSourceLocator;
import org.apache.xml.utils.WrappedRuntimeException;
....
public static SourceLocator getRootSourceLocator(Throwable exception)
{
SourceLocator locator = null;
Throwable cause = exception;
// Try to find the locator closest to the cause.
do
{
if(cause instanceof SAXParseException)
{
locator = new SAXSourceLocator((SAXParseException)cause);
}
else if (cause instanceof TransformerException)
{
SourceLocator causeLocator =
((TransformerException)cause).getLocator();
if(null != causeLocator)
locator = causeLocator;
}
if(cause instanceof TransformerException)
cause = ((TransformerException)cause).getCause();
else if(cause instanceof WrappedRuntimeException)
cause = ((WrappedRuntimeException)cause).getException();
else if(cause instanceof SAXException)
cause = ((SAXException)cause).getException();
else
cause = null;
}
while(null != cause);
return locator;
}
|
 |
 |
 |
 |
 |
Xalan-Java
exception handling: The exception architecture in Xalan-Java
and with transforms in general is tricky because of multiple layers
of exception handling, involving movement back and forth between
SAX and Transformer exceptions and across pipes. Xalan-Java often
uses a WrappedRuntimeException to throw over many layers of checked
exceptions, in order not to have every possible checked exception
be declared for every function in the stack, which means it has to
catch this exception at the upper levels and unwrap the exception
to pass it on as a TransformerException.
A JAXP 1.2 TransformerException often wraps another exception. Two
of the TransformerException structures that are frequently used to
construct contained exceptions in JAXP 1.2 do not set the locator.
The locator is not set because we don't know the type of exception
that the Throwable argument represents. The solution is to chase up
the contained exceptions to find the root cause, which will usually
have a location set for you. This can be somewhat tricky, as not
all the exceptions may be TransformerExceptions. A good sample is
in the DefaultHandler static printLocation() method, which the
Xalan-Java command-line processor uses to report errors. You can
also roll your own functions along the lines of the
getRootSourceLocator() example above. |
|
|