如何离线使用dom4j SAXReader?

4

我想离线使用SAXReader进行工作,但问题是SAXReader会根据DTD验证xml。我不想更改DTD或XML中的任何其他内容。在这个网站和其他来源上搜索后,我发现两个答案没有帮助我:

  1. 使用EntityResolver绕过网络调用
  2. 使用setIncludeExternalDTDDeclarations(false)

下面是我尝试的示例:

protected Document getPlistDocument() throws MalformedURLException,
DocumentException {
    SAXReader saxReader = new SAXReader();
    saxReader.setIgnoreComments(false);
    saxReader.setIncludeExternalDTDDeclarations(false);
    saxReader.setIncludeInternalDTDDeclarations(true);
    saxReader.setEntityResolver(new MyResolver());
    Document plistDocument = saxReader.read(getDestinationFile().toURI().toURL());
    return plistDocument;
}

public class MyResolver implements EntityResolver {
    public InputSource resolveEntity (String publicId, String systemId)
    {
        if (systemId.equals("http://www.myhost.com/today")) {
            // if we want a custom implementation, return a special input source
            return null;

        } else {
            // use the default behaviour
            return null;
        }
    }
}

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">

我仍然无法离线工作,请给予建议...谢谢。 堆栈跟踪:
14:20:44,358 ERROR [ApplicationBuilder] iphone build failed: Resource Manager - Problem handle Root.plist: www.apple.com Nested exception: www.apple.com
com.something.builder.sourcemanager.exception.SourceHandlingException: Resource Manager - Problem handle Root.plist: www.apple.com Nested exception: www.apple.com
****
****
Caused by: org.dom4j.DocumentException: www.apple.com Nested exception: www.apple.com
at org.dom4j.io.SAXReader.read(SAXReader.java:484)
at org.dom4j.io.SAXReader.read(SAXReader.java:291)  
... 10 more

你遇到了什么错误?它是否抛出了任何异常?你能否发布此类异常的消息和堆栈跟踪? - Tomas Narros
4个回答

5

您的实体解析器没有处理任何内容(因为它始终返回null)。请在系统ID为http://www.apple.com/DTDs/PropertyList-1.0.dtd时,使其返回一个指向实际DTD文件的InputSource,因为这是dom4j尝试下载的DTD。

public class MyResolver implements EntityResolver {
    public InputSource resolveEntity (String publicId, String systemId)
    {
        if (systemId.equals("http://www.apple.com/DTDs/PropertyList-1.0.dtd")) {
            return new InputSource(MyResolver.class.getResourceAsStream("/dtds/PropertyList-1.0.dtd");
        } else {
            // use the default behaviour
            return null;
        }
    }
}

例如,此实现从类路径(在包 dtds 中)返回DTD。您只需要自行下载DTD并将其捆绑到应用程序中,在包 dtds 中即可。

0

作为一种选择,如果您想离线使用SAXReader,则可以通过http://apache.org/xml/features/nonvalidating/load-external-dtd Xerces功能禁用其外部DTD获取。

根据Xerces功能文档,将其设置为false会使SAXReader完全忽略外部DTD。

这个SO答案有一个代码示例。


0
请注意,您实际上并未针对DTD进行验证。要实现这一点,您需要执行以下操作:
SAXReader saxReader = new SAXReader(true);

否则JB是对的 - 他比我早3分钟进来了!

-1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接