My program reads in a document from a location that is not the project root directory. The doc contains a relative path. When the program applies that path, it does start from the project's root directory. How can I make it apply the path from the document's original location?
Here are the details. Kind of long, but pretty straightforward.
I have a Java project in Eclipse located at
C:\one\two\three\four\five
The program runs an XSL transform that takes a Schematron schema as input and produces a new XSLT stylesheet as output. The schema is located at
C:\one\two\three\four\five\six\S\P\schema.sch
It contains this line, and several more like it:
<sch:let name="foo" select="document('../../C/P/bar.xml')"/>
If you start from the location of the schema and apply that relative path, you end up with
C:\one\two\three\four\five\six\C\P\bar.xml
which is the correct location of bar.xml
. However, when I run my program, I get a number of errors, which all seem to be similar or related to this one:
Recoverable error on line 1262
FODC0002: I/O error reported by XML parser processing
file:/C:/one/two/three/C/P/bar.xml:
C:\one\two\three\C\P\bar.xml (The system cannot find the path specified)
FODC0002
is the error code for "Error retrieving resource." That makes sense, because this is not the correct location of bar.xml
. It seems that the relative path is being applied to the project's root directory. This is the relevant code:
void compileToXslt(byte[] schema) throws Exception {
XsltCompiler comp = Runtime.getSaxonProcessor().newXsltCompiler();
comp.setURIResolver(resolver);
Source source = resolver.resolve("iso_svrl_for_xslt2.xsl", null);
XsltExecutable executable = comp.compile(source);
XsltTransformer transformer = executable.load();
transformer.setSource(new StreamSource(new ByteArrayInputStream(schema)));
Serializer serializer = new Serializer();
serializer.setOutputStream(new ByteArrayOutputStream());
transformer.setDestination(serializer);
transformer.transform(); // Errors appear in logs during this line
// ...
Source
is javax.xml.transform.Source
. The XSL-related classes are all from SAXON (Javadoc).
What can I do to fix this? Moving bar.xml
to the location where the program is looking for it, and editing style.xsl
, are not options for me, because both files belong to a third-party library.
UPDATE:
Further research has led me to believe that I need to set the system ID of the StreamSource
. I tried replacing the transformer.setSource(...
line with this:
StreamSource strSrc = new StreamSource(new ByteArrayInputStream(schema));
strSrc.setSystemId(new
File("C:\\one\\two\\three\\four\\five\\six\\S\\P\\schema.sch").toURI()
.toURL().toExternalForm());
transformer.setSource(strSrc);
but I'm getting the same results. Am I using setSystemId()
incorrectly? Am I going down the wrong path entirely?