Validating XML, but specify where DTD doc is, at runtime?
843834Aug 10 2001 — edited May 30 2002Hi all.
I've looked through a lot of posts in this forum and still cannot find the solution to this problem, so maybe someone here can help me?
The problem is this:
I am using a servlet to read in an ordinary XML document, with a normal <!DOCTYPE declaration and validate it. This works great if the DTD file is either located at a specific location on the web server (ie, somewhere that the webserver already looks at as part of it's enviroment) or if I hard code the location of the DTD in the <!DOCTYPE line in the XML doc.
I want to be able to tell the validating parser (javax.xml.parser.DocumentBuilder) what the actual path to the DTD is. So that if the <!DOCTYPE tag specifies "mydtd.dtd" as the file, then I can then give the parser the path to that file. Does that make any sense?
I tried using an EntityResolver class etc, but it doesn't do anything. Here is my code:
javax.xml.parsers.DocumentBuilderFactory docFact = javax.xml.parsers.DocumentBuilderFactory.newInstance();
docFact.setValidating(true);
javax.xml.parsers.DocumentBuilder docBuilder = docFact.newDocumentBuilder();
MyResolver r = new MyResolver();
r.resolveEntity(null,"mydtd.dtd");
docBuilder.setErrorHandler(new ErrorHandler() {
public void error(SAXParseException e) throws SAXException {
throw new SAXException(e);
}
public void fatalError(SAXParseException e) throws SAXException {
throw new SAXException(e);
}
public void warning(SAXParseException e) {
}
});
docBuilder.setEntityResolver(r);
docBuilder.parse(new InputSource(ClassLoader.getSystemResourceAsStream("xmltestservlet/myxml.xml")));
class MyResolver implements EntityResolver {
public InputSource resolveEntity (String publicId, String systemId)
{
java.io.InputStream in = ClassLoader.getSystemResourceAsStream("xmltestservlet/"+systemId);
return new InputSource(in);
}
}
------------------------------------------------
This is the error message that I get :
org.xml.sax.SAXParseException: File "file:///d:/iPlanet/Servers/https-mucci/config/mydtd.dtd" not found.
This is because I dont want to keep my dtd file in this directory! I specified in the entityResolver method that I want the actual DTD file to come from the same location as the class files are held. (They are accessed through the ClassLoader.getSystemResourceAsStream() call).
Does anyone have any ideas, or has anyone been down this road before?
Thanks
P.S The contents of my XML and DTD files are below (both are held in the same package as the class files):
<?xml version='1.0' encoding='utf-8'?>
<!-- A SAMPLE set of slides -->
<!DOCTYPE MYXML SYSTEM "mydtd.dtd">
<MYXML>
<ITEM>dfdsf</ITEM>
<ITEM>dsfsfsdfsd</ITEM>
</MYXML>
<?xml version='1.0' encoding='utf-8'?>
<!ELEMENT MYXML (ITEM+)>
<!ELEMENT ITEM (#PCDATA)>
Andy