2009-10-30 6 views
7

voglio analizzare il seguente documento XML per risolvere tutte le entità in esso:Java: Come prevenire 'systemId' in EntityResolver # resolveEntity (String publicId, String systemId) di essere assolutizzato a corrente directory di lavoro

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

mio EntityResolver dovrebbe prendere l'entità esterna con il dato ID di sistema dal database e poi fare la risoluzione, vedi sotto per un esempio:

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) e SAX (XMLReader) , imposta il resolver dell'entità su MyEnt ityResolver (vale a dire setEntityResolver(new MyEntityResolver())), ma systemId in MyEntityResolver#resolveEntity(String publicId, String systemId) è sempre stato assolutizzato alla 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 ciò che volevo?

Grazie!

risposta

7

Apparentemente, esiste un'altra interfaccia denominata EntityResolver2 che è l'estensione del vecchio EntityResolver. (Parla di nomi confusi!)

In ogni caso, ho trovato che EntityResolver2 ha ottenuto ciò che volevo, ovvero non apporta alcuna modifica allo systemId, quindi sarà sempre esattamente ciò che è stato specificato nel documento XML.

0

Da the EntityResolver Javadocs:

Se l'identificatore di sistema è un URL, il parser SAX deve risolvere completamente prima di segnalarlo alla domanda .

Inoltre, il org.xml.sax docs hanno questo da dire sulla funzionalità di determinazione-dtd-URI:

Essa non si applica ai EntityResolver.resolveEntity(), che non è utilizzato per segnalare le dichiarazioni. ..

Penso che sia necessario impostare l'URI di base su qualcosa con cui si può convivere, o utilizzare ID pubblici invece di ID di sistema.