4

SAXReader をオフラインで使用したいのですが、問題は SAXReader が DTD に従って xml を検証していることです。DTD やその他の XML を変更したくありません。このウェブサイトや他の情報源を検索したところ、役に立たなかった2 つの回答が見つかりました。

  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
4

3 に答える 3

5

エンティティ リゾルバーは何も処理しません (常に null を返すため)。システム ID が の場合、実際の DTD ファイルに InputSource を返すようにしhttp://www.apple.com/DTDs/PropertyList-1.0.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 を自分でダウンロードして、アプリの package にバンドルするだけですdtds

于 2012-01-15T08:01:01.967 に答える
0

オプションとして、SAXReader をオフラインで使用するだけの場合は、http://apache.org/xml/features/nonvalidating/load-external-dtdXerces 機能を介して外部 DTD フェッチを無効にします。

Xerces features documentationによると、これをfalseに設定すると、SAXReader は外部 DTD を完全に無視します。

この SO 回答にはコード例があります。

于 2014-05-02T15:58:35.380 に答える
0

また、実際には DTD に対して検証を行っているわけではないことに注意してください。それを達成するには、次のことを行う必要があります。

SAXReader saxReader = new SAXReader(true);

そうでなければ、JB の言うとおりです。彼は私より 3 分早く到着しました。

于 2012-01-15T08:23:44.497 に答える