Sax - ExpatParser$ParseException

Posted

技术标签:

【中文标题】Sax - ExpatParser$ParseException【英文标题】: 【发布时间】:2012-02-08 06:22:18 【问题描述】:

我正在制作一个读取 XML Internet 的 android 应用程序。此应用程序使用 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 行,第 4 列 42:格式不正确(无效令牌)

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

为什么相同的代码在 Java SE 应用程序中运行良好,而不是在 Android 中运行?另一方面,如何解决这个问题?

感谢您的帮助。

您好。

【问题讨论】:

你能分享你的 xml 吗?根据错误,你的 xml 有问题 .. @MohitSharma 但是,为什么相同的代码在 Java SE 应用程序中运行良好,而不是 Android?。这是网址:aemet.es/xml/municipios/localidad_33002.xml 原来我认为你的 xml 有一些问题,根据错误.. 但它不是那样的......现在你唯一的解决方案是你已经调试了解析 也许这与编码有关?你使用 UTF-8 吗?我不知道Android的具体情况。 @Ikuti 我没有指定编码。我没有指定编码。 Android中是否需要?,Java好像不是必须的。 【参考方案1】:

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

然后,您需要告诉 SAXParser 使用哪个字符集。这样做的一种方法是将InputSource(而不是 URL)传递给 parse 方法。举个例子:

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 VM不支持这种编码,抛出org.apache.harmony.xml.ExpatParser$ParseException: At line 1, column 0: unknown encoding异常。 作为 ISO-8859-15,它主要与 ISO-8859-1 兼容,除了一些特定字符(如您所见 here),解决方法是在 setEncoding 方法中将 ISO-8859-15 值更改为 ISO-8859-1,强制解析器使用不同但兼容的字符集编码:

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

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

【讨论】:

嗨@tomas-narros,谢谢,我会尝试,你会注意到结果。 解析器不应该精确地使用XML声明来选择合适的编码吗? 这是一个很好的观点@JB。当然应该。但我很确定这是一个编码问题。 @Lobo:好的。 Android VM 似乎不支持这种编码。作为 ISO-8859-15,它主要与 ISO-8859-1 兼容,除了一些特定字符(如您在 en.wikipedia.org/wiki/ISO/IEC_8859-15 看到的那样),我会尝试将 ISO-8859-15 值更改为 ISO-8859-1设置编码方法。似乎只要您的 Android 不支持字符集,它就会使用其默认值 (UTF-8),因此解析器无法使用 XML 声明来选择合适的编码。请检查并告诉我它是否有效 @Lobo:我很高兴听到这个消息。我将更新完整答案,以提供解决方案以供将来参考。

以上是关于Sax - ExpatParser$ParseException的主要内容,如果未能解决你的问题,请参考以下文章

XML- SAX解析

SAX 与 XmlTextReader - C# 中的 SAX

SAX - DefaultHandler

sax的解析原理基础

使用 SAX 读取 XML,跳过传递 org.xml.sax.SAXParseException 的节点

Java 操作XML (org.xml.sax)