Java:如何防止 EntityResolver#resolveEntity(String publicId, Stri

时间:2023-01-14
本文介绍了Java:如何防止 EntityResolver#resolveEntity(String publicId, String systemId) 中的“systemId"被绝对化到当前工作目录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着跟版网的小编来一起学习吧!

问题描述

我想解析以下 XML 文档以解析其中的所有实体:

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

我的 EntityResolver 应该从数据库中获取具有给定系统 ID 的外部实体,然后进行解析,请参见下图:

 私有静态类 MyEntityResolver{public InputSource resolveEntity(String publicId, String systemId)抛出 SAXException、IOException{//此时systemId总是被绝对化为当前工作目录,//即使 XML 文档将其指定为相对的.//例如file:///H:/mydoc.dtd" 而不仅仅是mydoc.dtd"//为什么???我怎样才能防止这种情况???SgmlEntity 实体 = findEntityFromDatabase(systemId);InputSource is = new InputSource(new ByteArrayInputStream(entity.getContents()));is.setPublicId(publicId);is.setSystemId(systemId);回报是;}}

我尝试使用 DOM (DocumentBuilder) 和 SAX (XMLReader),将实体解析器设置为 MyEntityResolver(即 setEntityResolver(new MyEntityResolver())),但 systemIdMyEntityResolver#resolveEntity(String publicId, String systemId) 中总是被绝对化到当前工作目录.

我也尝试调用 setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);,但没有任何帮助.p>

那么我怎样才能实现我想要的呢?

谢谢!

解决方案

显然还有一个接口叫EntityResolver2 是旧 EntityResolver.(谈论令人困惑的名字!)

无论如何,我发现 EntityResolver2 实现了我想要的,也就是说,它没有对 systemId 进行任何更改,所以它始终是指定的在 XML 文档中.

I want to parse the following XML document to resolve all entities in it:

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

My EntityResolver is supposed to fetch the external entity with the given system ID from the database and then do the resolution, see below for an illustration:

 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;
    }
 }

I tried both using DOM (DocumentBuilder) and SAX (XMLReader), set the entity resolver to MyEntityResolver (i.e. setEntityResolver(new MyEntityResolver())), but systemId in MyEntityResolver#resolveEntity(String publicId, String systemId) is always being absolutized to the current working directory.

I also tried calling setFeature("http://xml.org/sax/features/resolve-dtd-uris", false);, but that didn't help anything.

So how can I achieve what I wanted?

Thanks!

解决方案

Apparently, there is another interface called EntityResolver2 which is the extension of the old EntityResolver. (Talk about confusing names!)

Anyway, I found that EntityResolver2 achieved what I wanted, that is, it does not make any changes to the systemId, so it will always exactly be what was specified in the XML document.

这篇关于Java:如何防止 EntityResolver#resolveEntity(String publicId, String systemId) 中的“systemId"被绝对化到当前工作目录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!

上一篇:从流输入中解析没有根元素的 XML 片段列表 下一篇:如何通过 JAXB xml 解析获取特定元素?

相关文章

最新文章