java 为什么在使用 SAXParser 时会收到“MalformedURLException: no protocol”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3677517/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 02:58:22  来源:igfitidea点击:

Why am I getting "MalformedURLException: no protocol" when using SAXParser?

javaxmlsaxparser

提问by user26270

I'm copying code from one part of our application (an applet) to inside the app. I'm parsing XML as a String. It's been awhile since I parsed XML, but from the error that's thrown it looks like it might have to do with not finding the .dtd. The stack trace makes it difficult to find the exact cause of the error, but here's the message:

我正在将代码从我们应用程序的一部分(一个小程序)复制到应用程序内部。我将 XML 解析为字符串。自从我解析 XML 已经有一段时间了,但是从抛出的错误来看,它看起来可能与找不到 .dtd 有关。堆栈跟踪使得很难找到错误的确切原因,但以下是消息:

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

and the XML has this as the first couple lines:

并且 XML 将其作为前几行:

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

and here's the relevant code snippets

这是相关的代码片段

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

}

It looks like the error is happening in the preparseString() method, on the line that actually does the parsing, the m_SaxParser.parse(lSource, this);line.

看起来错误发生在 preparseString() 方法中,在实际进行解析的m_SaxParser.parse(lSource, this);行上,行。

FYI, the 'MyComp.dtd' file does exist at that location and is accessible via http. The XML file comes from a different service on the server, so I can't change it to a file:// format and put the .dtd file on the classpath.

仅供参考,“MyComp.dtd”文件确实存在于该位置并可通过 http 访问。XML 文件来自服务器上的不同服务,因此我无法将其更改为 file:// 格式并将 .dtd 文件放在类路径上。

采纳答案by John Engelman

I think you have some extra code in the XML declaration. Try this:

我认为您在 XML 声明中有一些额外的代码。试试这个:

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

The above was captured from the W3C Recommendations: http://www.w3.org/QA/2002/04/valid-dtd-list.html

以上内容摘自 W3C 建议:http: //www.w3.org/QA/2002/04/valid-dtd-list.html

You can use the http link to set the Schema on the SAXParserFactory before creating your parser.

在创建解析器之前,您可以使用 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);

回答by Stephen C

The problem is that this:

问题在于:

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

is an HTML hyperlink, not a URL. Replace it with this:

是 HTML 超链接,而不是 URL。用这个替换它:

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

回答by J?rn Horstmann

Since this XML comes from an external source, the first thing to do would be to complain to them that they are sending invalid XML.

由于此 XML 来自外部来源,因此首先要做的是向他们抱怨他们发送的 XML 无效。

As a workaround, you can set an EntityResolveron your parser that compares the SystemId to this invalid url and returns a correct http url:

作为一种解决方法,您可以在解析器上设置一个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;
            }
        }
    }
);