Java: Come impedire che 'systemId' in EntityResolver # resolEntity (String publicId, String systemId) venga assolutizzato nella directory di lavoro corrente
-
22-07-2019 - |
Domanda
Voglio analizzare il seguente documento XML per risolvere tutte le entità in esso contenute:
<!DOCTYPE doc SYSTEM 'mydoc.dtd'>
<doc>&title;</doc>
My EntityResolver dovrebbe recuperare l'entità esterna con l'ID di sistema specificato dal database e quindi eseguire la risoluzione, vedi sotto per un'illustrazione:
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;
}
}
Ho provato sia usando DOM (DocumentBuilder) che SAX (XMLReader), ho impostato il risolutore entità su MyEntityResolver (ovvero setEntityResolver (new MyEntityResolver ())
), ma systemId
in MyEntityResolver # solveEntity (String publicId, String systemId)
viene sempre assolutizzato nella directory di lavoro corrente.
Ho anche provato a chiamare setFeature (" http: //xml.org/sax/features/resolve-dtd-uris" ;, false);
, ma questo non ha aiutato nulla.
Quindi, come posso ottenere quello che volevo?
Grazie!
Soluzione
Apparentemente, c'è un'altra interfaccia chiamata EntityResolver2 che è l'estensione del vecchio EntityResolver . (Parla di nomi confusi!)
Ad ogni modo, ho scoperto che EntityResolver2
ha raggiunto ciò che volevo, cioè non ha apportato modifiche al systemId
, quindi sarà sempre esattamente ciò che è stato specificato nel documento XML.
Altri suggerimenti
Da l'EntityResolver Javadocs :
Se l'identificatore di sistema è un URL, il Il parser SAX deve risolverlo completamente prima di segnalarlo al applicazione.
Inoltre, org. Documenti xml.sax hanno da dire sulla funzione resol-dtd-uris:
Non si applica a EntityResolver.resolveEntity (), che non viene utilizzato per segnalare dichiarazioni ...
Penso che devi impostare l'URI di base su qualcosa con cui puoi convivere o utilizzare gli ID pubblici anziché gli ID di sistema.