¿Por qué recibo “MalformedURLException: ningún protocolo” cuando se utiliza SAXParser?

StackOverflow https://stackoverflow.com/questions/3677517

  •  01-10-2019
  •  | 
  •  

Pregunta

estoy copiando el código de una parte de nuestra aplicación (applet) que dentro de la aplicación. Estoy analizar XML como una cadena. Ha sido un tiempo desde que Analizada XML, pero a partir del error que ha echado todo apunta a que podría tener que ver con no encontrar la .dtd. El seguimiento de la pila hace que sea difícil encontrar la causa exacta del error, pero aquí está el mensaje:

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

y el XML tiene esto como el primer par de líneas:

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

y aquí los fragmentos de código correspondientes

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

}

Parece que el error está ocurriendo en el preparseString () método, en la línea que realmente hace el análisis, la línea m_SaxParser.parse(lSource, this);.

Para su información, el archivo 'MyComp.dtd' qué existe en ese lugar y es accesible a través de http. El archivo XML proviene de un servicio diferente en el servidor, así que no puedo cambiarlo a un file: // formato y poner el archivo .dtd en la ruta de clase.

¿Fue útil?

Solución

Yo creo que hay algo de código adicional en la declaración XML. Prueba esto:

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

Lo anterior fue capturado desde las Recomendaciones del W3C: http: //www.w3.org/QA/2002/04/valid-dtd-list.html

Puede utilizar el enlace http para establecer el esquema de la SAXParserFactory antes de crear el analizador.

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

Otros consejos

El problema es que esto:

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

es un hipervínculo HTML, no una URL. Reemplazarlo con esto:

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

Desde este XML proviene de una fuente externa, la primera cosa a hacer sería a quejarse a ellos que están enviando XML válido.

Como solución alternativa, se puede establecer un EntityResolver en su programa de análisis que compara la SystemId a esta URL no válida y devuelve una correcta URL http:

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;
            }
        }
    }
);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top