2012-03-28 13 views
5

Estoy usando Java 6. Quiero analizar XHTML que sé que está bien formado. Como tal, no quiero hacer ninguna validación contra los DTD u otros esquemas a los que se hace referencia en el documento. Sin embargo, estoy teniendo problemas para averiguar cómo desactivar esa validación. Tengo¿Cómo desactivo la validación al analizar XML bien formado con DocumentBuilder.parse?

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    factory.setValidating(false); 
    final DocumentBuilder b = factory.newDocumentBuilder(); 
    final InputSource s = new InputSource(new StringReader(str)); 
    org.w3c.dom.Document result = b.parse(s); 

Pero sigo teniendo una excepción en la última línea ...

java.net.SocketException: Unexpected end of file from server 
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:777) 
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:640) 
    at sun.net.www.http.HttpClient.parseHTTPHeader(HttpClient.java:774) 
    at sun.net.www.http.HttpClient.parseHTTP(HttpClient.java:640) 
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1195) 
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.setupCurrentEntity(XMLEntityManager.java:677) 
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startEntity(XMLEntityManager.java:1315) 
    at com.sun.org.apache.xerces.internal.impl.XMLEntityManager.startDTDEntity(XMLEntityManager.java:1282) 
    at com.sun.org.apache.xerces.internal.impl.XMLDTDScannerImpl.setInputSource(XMLDTDScannerImpl.java:283) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.dispatch(XMLDocumentScannerImpl.java:1194) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$DTDDriver.next(XMLDocumentScannerImpl.java:1090) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl$PrologDriver.next(XMLDocumentScannerImpl.java:1003) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648) 
    at com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808) 
    at com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737) 
    at com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119) 
    at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:235) 
    at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284) 
    at com.myco.myproj.util.XmlUtilities.getStringAsDocument(XmlUtilities.java:130) 
    at com.myco.myproj.util.NetUtilities.getUrlAsDocument(NetUtilities.java:30) 
    at com.myco.myproj.parsers.impl.AbstractChicagoReaderParser.parsePage(AbstractChicagoReaderParser.java:144) 
    at com.myco.myproj.parsers.impl.AbstractChicagoReaderParser.getEvents(AbstractChicagoReaderParser.java:112) 
    at com.myco.myproj.parsers.impl.ChicagoReaderParserTest.testParser(ChicagoReaderParserTest.java:29) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

Yo no quiero que mi analizador de ir a la Internet. ¿Cómo desactivo eso? Gracias, - de Dave

Editar: sugerencia de Per Traroth, probé el código de abajo, pero conseguir la misma excepción

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 
    factory.setValidating(false); 
    final DocumentBuilder builder = factory.newDocumentBuilder(); 
    builder.setEntityResolver(new EntityResolver() { 
     @Override 
      public InputSource resolveEntity(String publicId, String systemId) { 
        return null; 
      } 
     }); 
    final InputSource s = new InputSource(new StringReader(str)); 
    org.w3c.dom.Document result = builder.parse(s); 
+0

¿Qué pasa si muestra o iniciar sesión isValidating() para DocumentBuilderFactory? –

Respuesta

2

Probablemente relacionado con un tema EntityResolver. Puede echar un vistazo aquí:

How to read well formed XML in Java, but skip the schema?

+0

Supongo que estás hablando de la respuesta aceptada en ese hilo. Probé la sugerencia (mi código está incluido en la edición), pero sigo recibiendo la misma excepción. ¿Me estoy perdiendo de algo? – Dave

+1

@Dave - Sí. La devolución nula es lo mismo que no aplicar una resolución de entidad. Debe seguir la otra ruta para devolver una fuente de entrada. Simplemente cambie "foo.dtd" a la identificación del sistema de la DTD para su archivo XML. – Alohci

+0

Sí, si observa el código de muestra en la respuesta, verá que el método resolveEntity() devuelve un InputSource real no nulo si el XML se refiere a un DTD, y nulo a más. –

4

Así es como se crea un DocumentBuilder que ignorar todas las entidades de referencia externos, incluyendo DTD:

final DocumentBuilder builder = factory.newDocumentBuilder(); 
builder.setEntityResolver(new EntityResolver() { 
    @Override 
     public InputSource resolveEntity(String publicId, String systemId) { 
       // it might be a good idea to insert a trace logging here that you are ignoring publicId/systemId 
       return new InputSource(new StringReader("")); // Returns a valid dummy source 
     } 
    }); 
Cuestiones relacionadas