Java: Cómo evitar que 'systemId' en EntityResolver # resolveEntity (String publicId, String systemId) se absolutice al directorio de trabajo actual
-
22-07-2019 - |
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!
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.