Wednesday, November 23, 2005

Parsing an xml file without having access to the associated DTD

Pfffeww!
I have finally found the solution to my problem...
But lets start from the begin, well somewhat from the beginning.

I needed to change the logfile location as defined in a log4j.xml file from code.
So I started of with a DOM based solution using JDK1.4 features to parse the log4j.xml file, using jaxen to select nodes based on XPath expressions and then updating the found Node with the given value.

But... parsing the log4j.xml file failed because my application could not find the log4j.dtd file.
Removing the log4j.dtd file from the log4j.xml file solved the parsing problem but caused another problem, log4j would not accept the file anymore.
Also setting the validating flag to false did not solve the problem.

After searching the internet and trying several options, I found in the JBoss source code the solution, create inner class anonymous that implements the EntityResolver interface:
EntityResolver resolver = new EntityResolver () {
public InputSource resolveEntity (String publicId, String systemId) {
String empty = "";
ByteArrayInputStream bais = new ByteArrayInputStream(empty.getBytes());
System.out.println("resolveEntity:" + publicId + "|" + systemId);
return new InputSource(bais);
}
};
builder.setEntityResolver(resolver);

The returned InputSource consists solely of an empty string, this satisfises loading the dtd, since validation is set to false, the read document is not validated.
Now lets see if is actaully correctly written back to disk.