7

アプリケーションの一部 (アプレット) からアプリケーション内にコードをコピーしています。XML を文字列として解析しています。XML を解析してからしばらく経ちましたが、スローされたエラーから、.dtd が見つからないことに関係しているように見えます。スタック トレースではエラーの正確な原因を特定することは困難ですが、メッセージは次のとおりです。

java.net.MalformedURLException: no protocol: <a href="http://www.mycomp.com/MyComp.dtd">http://www.mycomp.com/MyComp.dtd</a>

XML の最初の数行は次のとおりです。

<?xml version='1.0'?>
<!DOCTYPE MYTHING  SYSTEM '<a href="http://www.mycomp.com/MyComp.dtd">http://www.mycomp.com/MyComp.dtd</a>'>

ここに関連するコードスニペットがあります

class XMLImportParser extends DefaultHandler {

  private SAXParser m_SaxParser = null;
  private String is_InputString = "";

  XMLImportParser(String xmlStr) throws SAXException, IOException {
    super();
    is_InputString = xmlStr;
    createParser();
    try {
      preparseString();
      parseString(is_InputString);
    } catch (Exception e) {
       throw new SAXException(e); //"Import Error : "+e.getMessage());
    }
  }

  void createParser() throws SAXException {
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    try {
        factory.setFeature("http://xml.org/sax/features/namespaces", true);
        factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
        m_SaxParser = factory.newSAXParser();
        m_SaxParser.getXMLReader().setFeature("http://xml.org/sax/features/namespaces", true);
        m_SaxParser.getXMLReader().setFeature("http://xml.org/sax/features/namespace-prefixes", true);
    } catch (SAXNotRecognizedException snre){
        throw new SAXException("Failed to create XML parser");  
    } catch (SAXNotSupportedException snse) {
        throw new SAXException("Failed to create XML parser");  
    } catch (Exception ex) {
        throw new SAXException(ex);  
    }
  }

  void preparseString() throws SAXException {
    try {
        InputSource lSource = new InputSource(new StringReader(is_InputString));
        lSource.setEncoding("UTF-8");
        m_SaxParser.parse(lSource, this);
    } catch (Exception ex) {
        throw new SAXException(ex);
    }
  }

}

preparseString() メソッドで、実際に解析を行う行でエラーが発生しているようm_SaxParser.parse(lSource, this);です。

参考までに、「MyComp.dtd」ファイルはその場所に存在し、http 経由でアクセスできます。XML ファイルはサーバー上の別のサービスから取得されるため、file:// 形式に変更して .dtd ファイルをクラスパスに配置することはできません。

4

3 に答える 3

6

XML 宣言に余分なコードがあると思います。これを試して:

<?xml version='1.0'?>
<!DOCTYPE MYTHING  SYSTEM "http://www.mycomp.com/MyComp.dtd">

上記は W3C 勧告からキャプチャされました: http://www.w3.org/QA/2002/04/valid-dtd-list.html

パーサーを作成する前に、http リンクを使用して SAXParserFactory にスキーマを設定できます。

void createParser() throws SAXException {
    Schema schema = SchemaFactory.newSchema(new URL("http://www.mycomp.com/MyComp.dtd"));
    SAXParserFactory factory = SAXParserFactory.newInstance();
    factory.setValidating(true);
    factory.setSchema(schema);
于 2010-09-09T14:30:57.403 に答える
4

問題はこれです:

<a href="http://www.mycomp.com/MyComp.dtd">http://www.mycomp.com/MyComp.dtd</a>

URL ではなく、HTML ハイパーリンクです。これを次のように置き換えます。

http://www.mycomp.com/MyComp.dtd
于 2010-09-09T14:34:31.320 に答える
1

この XML は外部ソースからのものであるため、最初にすべきことは、無効な XML を送信していることを彼らに訴えることです。

回避策として、パーサーにEntityResolverを設定して、SystemId をこの無効な URL と比較し、正しい http URL を返すことができます。

m_SaxParser.getXMLReader().setEntityResolver(
    new EntityResolver() {
        public InputSource resolveEntity(final String publicId, final String systemId) throws SAXException {
            if ("<a href=\"http://www.mycomp.com/MyComp.dtd\">http://www.mycomp.com/MyComp.dtd</a>".equals(systemId)) {
                return new InputSource("http://www.mycomp.com/MyComp.dtd");
            } else {
                return null;
            }
        }
    }
);
于 2010-09-09T16:00:42.800 に答える