tags:

views:

1561

answers:

7

The XML file I want to parse starts with :

<!DOCTYPE plist PUBLIC "-//...//DTD PLIST 1.0//EN" "http://www.....dtd"&gt;

So when I start the SAX praser, it tries to access this DTD online, and I get a java.net.UnknownHostException.

  1. I cannot modify the XML file before feeding it to the SAX parser
  2. I have to run even with no internet connection

How can I change the SAX Parser behaviour so that it does not try to load the DTD ? Thanks.

javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance();
factory.setValidating(false);

javax.xml.parsers.SAXParser parser = factory.newSAXParser();
parser.parse(xmlFile, handler);
+1  A: 

You can implement a custom EntityResolver which is what is used to lookup external entities during XML parsing.

org.xml.sax.EntityResolver customEntityResolver = new DummyEntityResolver();
javax.xml.parsers.SAXParser parser = factory.newSAXParser();
parser.getXMLReader().setEntityResolver(customEntityResolver);
parser.parse(xmlFile, handler);

And in your custom EntityResolver, just always return null. I think that should fix this problem.

Gowri
A: 

See related question. Should work for SAX as well as DOM.

toolkit
A: 

Hi Erik,

You should provide an EntityResolve to have the problem resolve. I will recommend you to write a resolver that will know how to read the DTDs locally instead (provided that you have them shipped together with your application). Otherwise, return null like Gowri suggested.

You might want to read up the the API doc.

yc

yclian
A: 

Thanks for your answers, I followed this hint and read the related question answer. It still does not work, the EntityResolver does not even seems to be called (System.out below does not show up). Here is my modified code:

 javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance();
 factory.setValidating(false);
 javax.xml.parsers.SAXParser parser = factory.newSAXParser();
 parser.getXMLReader().setEntityResolver(new org.xml.sax.EntityResolver() 
 {
  public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException 
  {
   System.out.println("Ignoring: " + publicId + ", " + systemId);
   return new org.xml.sax.InputSource(new java.io.StringReader(""));
  }
 });
 parser.parse(xmlFile, handler);
Eric Nicolas
+4  A: 

Ok, turns out the parse() method overrides any previously set entity resolvers with the handler passed in to the parse method. The following code should work:

javax.xml.parsers.SAXParserFactory factory = javax.xml.parsers.SAXParserFactory.newInstance();
factory.setValidating(false);
javax.xml.parsers.SAXParser parser = factory.newSAXParser();
parser.parse(new java.io.File("x.xml"), new org.xml.sax.helpers.DefaultHandler(){
        public org.xml.sax.InputSource resolveEntity(String publicId, String systemId)
                throws org.xml.sax.SAXException, java.io.IOException {
            System.out.println("Ignoring: " + publicId + ", " + systemId);
            return new org.xml.sax.InputSource(new java.io.StringReader(""));
        }
    });
Gowri
A: 

YESS !! Thanks very much Gowri. I didn't notice that the "DefaultHandler" was also an EntityResolver.

With your suggestion it works perfectly.

Eric Nicolas
A: 

works fine for me, too! Thanks a lot

Marc Giombetti