Джава:Как предотвратить абсолютизацию «systemId» в EntityResolver#resolveEntity(String publicId, String systemId) до текущего рабочего каталога
-
22-07-2019 - |
Вопрос
Я хочу проанализировать следующий XML-документ, чтобы разрешить все объекты в нем:
<!DOCTYPE doc SYSTEM 'mydoc.dtd'>
<doc>&title;</doc>
Предполагается, что мой EntityResolver извлекает внешний объект с заданным системным идентификатором из базы данных, а затем выполняет разрешение, см. иллюстрацию ниже:
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;
}
}
Я попробовал использовать как DOM (DocumentBuilder), так и SAX (XMLReader), установил для преобразователя объектов значение MyEntityResolver (т.е. setEntityResolver(new MyEntityResolver())
), но systemId
в MyEntityResolver#resolveEntity(String publicId, String systemId)
всегда абсолютизируется до текущего рабочего каталога.
Я также пытался позвонить setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);
, но это ничему не помогло.
Так как же мне добиться того, чего я хотел?
Спасибо!
Решение
Судя по всему, есть еще один интерфейс под названием EntityResolver2 который является продолжением старого EntityResolver.(Кстати, о запутанных именах!)
Во всяком случае, я нашел это EntityResolver2
достиг того, чего хотел, то есть не вносит никаких изменений в systemId
, поэтому всегда будет именно то, что указано в XML-документе.
Другие советы
От Javaдокументация EntityResolver:
Если идентификатор системы является URL -адресом, анализатор Sax должен полностью разрешить его, прежде чем сообщать о его приложении.
Так же документы org.xml.sax вот что можно сказать о функцииsolve-dtd-uris:
Это не распространяется на EntityResolver.Resolveentity (), который не используется для сообщений о объявлениях ...
Я думаю, вам нужно либо установить базовый URI на что-то, с чем вы можете жить, либо использовать общедоступные идентификаторы вместо системных идентификаторов.