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?