5

关于 Android 上使用 Java 的 Sax XML 解析器的问题:我需要解析从网络上获取的 XML 文件,而我无法控制。有些包含错误并导致解析器中止并出现“不匹配标签”或“格式不正确(无效令牌)”等错误。

这些错误对我来说无关紧要,我想忽略它们并继续前进,我可以处理损坏的 XML 结构。但我无法修复 XML 文件,它们不是我的。如何告诉 Android 上的 Sax(类 org.xml.sax.XMLReader)不要抛出异常并继续运行?附加 ErrorHandler 不起作用,捕获异常也没用,因为我无法在它停止的地方恢复解析。

我的 XML 不是 HTML,但这里有一些 (X)HTML 示例,浏览器会忽略错误并继续运行。我也想这样做。

  • 即使标签从未关闭,浏览器也可以使用“ <br> ”而不是“ <br/> ”。
  • 即使结束标签的顺序错误,“ <b><i> text </b></i> ”也能正常工作。
  • 尽管令牌无效,但“赔率和结束”被接受,“赔率和结束”将是正确的。

我宁愿不编写自己的解析器,处理字符集转换等等。我不需要验证 XML。这是我的代码,简化为要点:

XMLReader r = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
r.setErrorHandler(new MyLenientErrorHandlerThatNeverThrows());
r.setContentHandler(new MyImporterThatExtendsDefaultHandler());
r.parse(new InputSource(new BufferedReader(...)));

谢谢!

4

1 回答 1

2

Ok, it appears it can't be done. Sax supports error detection but not error recovery, which makes it less than ideal for robust code in this example. Got it to work by replaxing Sax with XmlPullParser, which allows wrapping the next-token call in a try-catch block:

try {
    XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
    XmlPullParser xpp = factory.newPullParser();
    xpp.setInput(in);
    int type = xpp.getEventType();
    while (type != XmlPullParser.END_DOCUMENT) {
        switch (type) {
          case XmlPullParser.START_TAG: startTag(xpp);             break;
          case XmlPullParser.END_TAG:   endTag(xpp);               break;
          case XmlPullParser.TEXT:      characters(xpp.getText()); break;
        }
        try {type = xpp.next();}
        catch (XmlPullParserException e) {}
    }
} catch (Exception e) {}
于 2012-03-02T12:07:57.087 回答