如何离线使用dom4j SAXReader?

时间:2012-01-12 08:27:50

标签: java xml dom4j

我想使用SAXReader 离线,问题是SAXReader正在验证xml是否符合DTD。我不想更改XML中的DTD或其他任何内容。通过在本网站和其他来源搜索,我找到了2个没有帮助我的答案:

  1. 使用EntityResolver绕过网络电话
  2. 使用setIncludeExternalDTDDeclarations(false)
  3. 我尝试做的例子:

    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
    

3 个答案:

答案 0 :(得分:5)

您的实体解析器不处理任何内容(因为它始终返回null)。当系统ID为http://www.apple.com/DTDs/PropertyList-1.0.dtd时,让它将InputSource返回到实际的DTD文件,因为这是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包中。

答案 1 :(得分:0)

另请注意,您实际上并未验证DTD。为此,您需要:

SAXReader saxReader = new SAXReader(true);

否则JB是对的 - 他在我面前3分钟到达!

答案 2 :(得分:0)

作为一个选项,如果您只想离线使用SAXReader,请通过http://apache.org/xml/features/nonvalidating/load-external-dtd Xerces禁用其外部DTD获取 特征

根据Xerces features documentation,将此设置为 false 会使SAXReader完全忽略外部DTD。

This SO answer有一个代码示例。