Sax - ExpatParser$ParseException

5

我正在开发一个读取XML网络的安卓应用程序。该应用程序使用SAX来解析XML。以下是我用于解析部分的代码:

public LectorSAX(String url){
    try{
        SAXParserFactory spf=SAXParserFactory.newInstance();
        SAXParser sp = spf.newSAXParser();
        DefaultHandler lxmlr=new LibraryXMLReader() ;
        sp.parse(url, lxmlr);

        nodo=((LibraryXMLReader)lxmlr).getNodoActual();

    }catch(ParserConfigurationException e){ 
        System.err.println("Error de parseo en LectorSAX.java: "+e);
    }catch(SAXException e){
        System.err.println("Error de sax LectorSAX.java: " + e);
    } catch (IOException e){
        System.err.println("Error de  io LectorSAX.java: " + e);
    }
}

问题在于发生了SAXException异常。异常信息如下:

org.apache.harmony.xml.ExpatParser$ParseException: 在第4行第42列: 不是格式良好的(无效的标记)

然而,如果我将相同的代码放入普通的Java SE应用程序中,则不会出现此异常,并且一切正常。

为什么相同的代码在Java SE应用程序中能够正常工作,但在Android中却不行?另外,如何解决这个问题?

谢谢您的帮助。

问候。


你能分享你的XML文件吗?根据错误消息,似乎存在XML问题。 - Code_Life
@MohitSharma,但是为什么在Java SE应用程序中相同的代码可以正常工作,而在Android中却不行呢?这是URL:http://www.aemet.es/xml/municipios/localidad_33002.xml。 - Lobo
最初我认为您的XML文件存在问题,导致出现错误...但事实并非如此...现在唯一的解决方案是您需要调试解析过程。 - Code_Life
也许这与编码有关吗?您使用的是UTF-8吗?我不了解Android的具体情况。 - Ludovic Kuty
@Ikuti 我没有指定编码。在Android中是否需要指定编码?似乎Java不是必需的。 - Lobo
1个回答

11

这可能是一个字符编码问题。
正如您所看到的,无效令牌错误指向第4行。
在此行中,您可以找到一个尖音符(Meteorología)和一个波浪符(España)。XML 头显示了 ISO-8859-15 编码值。由于它比 UTF 或 ISO-8859-1 编码更不常见,因此当 SAXParser 连接并尝试将字节内容转换为字符时,可能会导致错误,使用您的系统默认字符集。

然后,您需要告诉 SAXParser 使用哪个字符集。一种方法是将 InputSource 传递给解析方法,而不是 URL。例如:

SAXParserFactory factory = SAXParserFactory.newInstance();
SAXParser parser = factory.newSAXParser();

InputSource is = new InputSource(url);
is.setEncoding("ISO-8859-15");

DefaultHandler lxmlr=new LibraryXMLReader() ;
sp.parse(is, lxmlr);

编辑: 似乎Android虚拟机不支持此编码,会抛出一个org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: unknown encoding异常。
由于ISO-8859-15与ISO-8859-1兼容(除了一些特定字符,您可以在这里看到),一个解决方法是在setEncoding方法中将ISO-8859-15值更改为ISO-8859-1,强制解析器使用不同但兼容的字符集编码:

is.setEncoding("ISO-8859-1");

看起来,由于Android不支持声明的字符集,它使用其默认字符集(UTF-8),因此解析器无法使用XML声明选择适当的编码方式。


1
嗨@tomas-narros,谢谢,我会尝试并让您看到结果。 - Lobo
3
解释:XML声明包含了文档的编码方式,因此解析器应该使用XML声明来准确选择适当的编码方式。翻译:解析器应该精确地使用XML声明来选择适当的编码方式吗? - JB Nizet
1
这是个好观点 @JB。当然应该这样做。但我很确定这是一个编码问题。 - Tomas Narros
1
@Lobo:好的。看起来 Android 虚拟机不支持此编码。ISO-8859-15 主要与 ISO-8859-1 兼容,除了一些特定字符(可以在 http://en.wikipedia.org/wiki/ISO/IEC_8859-15 上查看),我建议将 setEncoding 方法中的 ISO-8859-15 值更改为 ISO-8859-1。似乎只要你的 Android 不支持该字符集,它就会使用其默认值(UTF-8),因此解析器不能使用 XML 声明来选择适当的编码方式。请检查并告诉我是否有效。 - Tomas Narros
1
@Lobo:很高兴听到这个消息。我会更新完整的答案,以便将来可以参考解决方案。 - Tomas Narros
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接