Java:EntityResolver#resolveEntity(String publicId、String systemId)の「systemId」が現在の作業ディレクトリに絶対化されないようにする方法
-
22-07-2019 - |
質問
次のXMLドキュメントを解析して、その中のすべてのエンティティを解決したい:
<!DOCTYPE doc SYSTEM 'mydoc.dtd'>
<doc>&title;</doc>
私のEntityResolverは、指定されたシステムIDを持つ外部エンティティをデータベースからフェッチし、解決を行うことになっています。以下の図を参照してください。
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(&quot; http://xml.org/sax/features/resolve-dtd-uris" ;, false);
の呼び出しも試みましたが、それは何の助けにもなりませんでした。
では、どうすれば自分の望みを達成できますか?
ありがとう!
解決
どうやら、 EntityResolver2 は、古い EntityResolver 。 (わかりにくい名前について話してください!)
とにかく、 EntityResolver2
は私が望むものを達成したこと、つまり systemId
に変更を加えないことがわかったので、常に正確に指定されたものになりますXMLドキュメント内。
他のヒント
システム識別子がURLの場合、 SAXパーサーは完全に解決する必要があります に報告する前に アプリケーション。
また、 org。 xml.saxドキュメントには、resolve-dtd-uris機能について次のように記載されています。
適用されない EntityResolver.resolveEntity()、これ 宣言の報告には使用されません...
base-URIを一緒に住めるものに設定するか、システムIDではなくパブリックIDを使用する必要があると思います。