Java: Cómo evitar que 'systemId' en EntityResolver # resolveEntity (String publicId, String systemId) se absolutice al directorio de trabajo actual

StackOverflow https://stackoverflow.com/questions/1648291

Pregunta

Deseo analizar el siguiente documento XML para resolver todas las entidades que contiene:

 <!DOCTYPE doc SYSTEM 'mydoc.dtd'>
 <doc>&title;</doc>

Se supone que My EntityResolver debe buscar la entidad externa con la ID del sistema dada de la base de datos y luego hacer la resolución, vea a continuación una ilustración:

 private static class MyEntityResolver
 {
    public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException
    {
        // At this point, systemId is always absolutized to the current working directory, 
        // even though the XML document specified it as relative.
        // E.g. "file:///H:/mydoc.dtd" instead of just "mydoc.dtd"
        // Why???  How can I prevent this???

        SgmlEntity entity = findEntityFromDatabase(systemId);
        InputSource is = new InputSource(new ByteArrayInputStream(entity.getContents()));
        is.setPublicId(publicId);
        is.setSystemId(systemId);
        return is;
    }
 }

Intenté usar DOM (DocumentBuilder) y SAX (XMLReader), establecí la resolución de entidad en MyEntityResolver (es decir, setEntityResolver (nuevo MyEntityResolver ()) ), pero systemId en MyEntityResolver # resolveEntity (String publicId, String systemId) siempre se absolutiza en el directorio de trabajo actual.

También intenté llamar a setFeature (" http: //xml.org/sax/features/resolve-dtd-uris" ;, false); , pero eso no ayudó en nada.

Entonces, ¿cómo puedo lograr lo que quería?

¡Gracias!

¿Fue útil?

Solución

Aparentemente, hay otra interfaz llamada EntityResolver2 , que es la extensión del antiguo EntityResolver . (¡Habla sobre nombres confusos!)

De todos modos, descubrí que EntityResolver2 logró lo que quería, es decir, no realiza ningún cambio en el systemId , por lo que siempre será exactamente lo que se especificó en el documento XML.

Otros consejos

De los Javadocs de EntityResolver :

  

Si el identificador del sistema es una URL, el   El analizador SAX debe resolverlo completamente   antes de informarlo al   aplicación.

Además, la org. los documentos xml.sax tienen esto que decir sobre la función resolve-dtd-uris:

  

No se aplica a   EntityResolver.resolveEntity (), que   no se usa para informar declaraciones ...

Creo que debes configurar tu URI base para algo con lo que puedas vivir, o usar ID públicos en lugar de ID de sistema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top