Java: Как предотвратить 'systemId' в EntityResolver#resolEntity(String publicId, String systemId) от абсолютизации до текущего рабочего каталога
Я хочу проанализировать следующий 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);
, но это ничего не помогло.
Так как же я могу достичь того, чего хотел?
Спасибо!
2 ответа
По-видимому, существует еще один интерфейс под названием EntityResolver2, который является расширением старого EntityResolver. (Разговор о запутанных именах!)
Во всяком случае, я обнаружил, что EntityResolver2
достиг того, что я хотел, то есть он не вносит никаких изменений в systemId
, так что это всегда будет именно то, что было указано в документе XML.
Если системный идентификатор является URL-адресом, анализатор SAX должен полностью разрешить его, прежде чем сообщать об этом приложению.
Кроме того, в документации org.xml.sax есть следующее, что можно сказать о функции resol-dtd-uris:
Это не относится к EntityResolver.resolveEntity(), который не используется для сообщения объявлений...
Я думаю, что вы должны либо установить базовый URI на то, с чем вы можете жить, либо использовать публичные идентификаторы вместо системных идентификаторов.