简体   繁体   中英

how to use dom4j SAXReader offline?

I would like to work with SAXReader offline , the problem is that SAXReader is verifying the xml accoerding to the DTD. I don't want to change the DTD or anything else in the XML. From searching on this website and other sources I found 2 answers that did not help me:

  1. use EntityResolver to bypass the network call
  2. use setIncludeExternalDTDDeclarations(false)

Example of what I tried to do:

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">

I'm still unable to work offline, please advice... thanks

StackTrace:

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

Your entity resolver doesn't handle anything (since it always returns null). Make it return an InputSource to the actual DTD file when the system ID is http://www.apple.com/DTDs/PropertyList-1.0.dtd , since that's the DTD that dom4j tries downloading.

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

This implementation, for example, returns the DTD from the classpath (in the package dtds ). You just have to download the DTD yourself and bundle it in your app, in the package dtds .

As an option, if you want to just use SAXReader offline, disable its external DTD fetching via the http://apache.org/xml/features/nonvalidating/load-external-dtd Xerces feature.

According Xerces features documentation , setting this to false makes SAXReader ignore the external DTD completely.

This SO answer has a code example.

Note, too, that you're not actually validating against the DTD. To accomplish that, you need to do:

SAXReader saxReader = new SAXReader(true);

Otherwise JB's right - he got in 3 mins before me!

我使用 NoOpEntityResolver 禁用在线 dtd,请参阅本网站中的代码: https ://cheatsheetseries.owasp.org/cheatsheets/XML_External_Entity_Prevention_Cheat_Sheet.html#no-op-entityresolver

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM