2011-01-18 15 views
10

tengo el siguiente código de Java:analizar un archivo XML con un esquema DTD en una ruta relativa

 

DocumentBuilder db=DocumentBuilderFactory.newInstance().newDocumentBuilder(); 
Document doc=db.parse(new File("/opt/myfile")); 
 

Y /opt/myfile contiene algo como:

 
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE archive SYSTEM "../../schema/xml/schema.dtd"> 
... 

me sale el siguiente error:

 
java.io.FileNotFoundException: /../schema/xml/schema.dtd (No such file or directory) 

Este es un marco grande de Java que consume un archivo XML producido en otro lugar. Creo que el camino relativo es el problema. No creo que sea aceptable cambiar el cwd antes de que comience la JVM (la ruta proviene de un archivo de configuración que es leído por la propia JVM) y no he encontrado una manera de cambiar el cwd mientras se ejecuta la JVM. ¿Cómo analizo este archivo XML con la DTD apropiada?

Respuesta

17

Debe usar un EntityResolver personalizado para modificar la ruta de la DTD para que pueda encontrarla. Por ejemplo:

db.setEntityResolver(new EntityResolver() { 
    @Override 
    public InputSource resolveEntity(String publicId, String systemId) 
      throws SAXException, IOException { 
     if (systemId.contains("schema.dtd")) { 
      return new InputSource(new FileReader("/path/to/schema.dtd")); 
     } else { 
      return null; 
     } 
    } 
}); 

Si schema.dtd está en la ruta de clases, sólo puede utilizar getResourceAsStream para cargarlo, sin especificar la ruta completa:

return new InputSource(Foo.class.getResourceAsStream("schema.dtd")); 
+1

o podría usar un sistema de resolución basado en catálogo. –

+0

Ejemplo de resolución lista para usar: [org.hibernate.util.DTDEntityResolver] (http://stackoverflow.com/questions/10886453/hibernate-issue-with-using-http-www-hibernate-org-dtd) – Vadzim

0

Utilicé el EntityResolver personalizado como en el ejemplo anterior pero aún busqué el archivo DTD en otro directorio base. Así que lo debujeé y luego descubrí que necesito cambiar la propiedad user.dir del sistema. Así que agregué esta línea al método de inicialización de mi aplicación y funciona ahora.

System.setProperty("user.dir") 
Cuestiones relacionadas