There's a nasty bug in createReader() with respect to a SAX entityResolver hook.
The problem is that createReader() takes both an InputSource and a systemId as arguments, and they aren't necessarily the same. If a SAX entityResolver hook has returned an InputSource, then the systemId passed to createReader() has nothing to do with the systemId of the InputSource. BUT, if the InputSource passed to createReader doesn't have a bytestream, createReader attempts to create one from the systemId: InputStream is = source.getByteStream(); if (is == null) { // create url and open the stream URL url = new URL(systemId); is = url.openStream(); } But this is the wrong system identifier. Alas, the simple-seeming fix, using the systemId of the source: InputStream is = source.getByteStream(); if (is == null) { // create url and open the stream URL url = new URL(source.getSystemId()); is = url.openStream(); } Doesn't work because in the *non* entityResolver case, the systemId of the source is relative but the systemId passed to createReader() is absolute. And you can't use the relative one here. Now, it would seem possible to work around this bug by creating the byteStream in the entityResolver hook, but I don't think that should be necessary. Help! Be seeing you, norm -- Norman Walsh <[EMAIL PROTECTED]> | It is as bad as you think. And http://nwalsh.com/ | they are out to get you.