7
votes

Pourquoi suis-je "Malformedurlexception: aucun protocole" lors de l'utilisation de saxparser?

Je copie du code d'une partie de notre application (une applet) à l'intérieur de l'application. Je parsing xml comme une chaîne. Cela fait longtemps que je n'ai pas analysé XML, mais à partir de l'erreur qui est lancée, on dirait que cela pourrait avoir à voir avec ne pas trouver le .dtd. La trace de la pile rend difficile de trouver la cause exacte de l'erreur, mais voici le message suivant:

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

}


0 commentaires

3 Réponses :


6
votes

Je pense que vous avez du code supplémentaire dans la Déclaration XML. Essayez ceci:

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


2 commentaires

Merci pour la réponse rapide. Je pense que c'est la réponse la plus complète avec la balise doctype corrigée complète. S'il vous plaît voir ma question ci-dessus sur la possibilité d'ignorer cette étiquette de DOCTYPE depuis que je l'obtiens à une source externe.


Vous pouvez définir le schéma sur la SaxparserFactory sur une créée à partir du lien HTTP. Je posterai une modification à la réponse ci-dessus.



4
votes

Le problème est que ceci:

http://www.mycomp.com/MyComp.dtd


4 commentaires

Merci, ça l'a fait. J'ai eu une copie locale du XML et l'a changé. Cependant, lorsque vous courez en direct, je ne peux pas modifier cette ligne DOCTYPE car je l'obtiens à partir d'un service externe. Alors, y a-t-il un moyen de dire à l'analyseur de l'ignorer? Je vois des références à la validation / à la non-validation dans d'autres parties du code qui me permettent de me demander si la non-validation permettrait d'ignorer la référence de la mauvaise DTD.


Définir votre analyseur à la non-validation entraînera l'ignorer de l'ensemble de la DTD. La raison d'avoir la DTD est de sorte que l'analyseur puisse valider l'entrée XML contre elle.


@ Codeman73 - Vous devriez essayer d'obtenir ce qui vous donne que Doctype est corrigé. C'est clairement faux.


@John, la validation invalidante n'arrêtera pas l'analyseur de lire la DTD. La DTD peut également définir des entités et attribuer des valeurs par défaut nécessaires pour analyser le XML.



1
votes

Étant donné que ce XML provient d'une source externe, la première chose à faire serait de se plaindre à eux qu'ils envoient des XML invalides.

comme solution de contournement, vous pouvez définir un EntityResolver sur votre analyseur compare le système Systemid à cette URL invalide et renvoie un URL HTTP correcte: P>

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


0 commentaires