SAX处理特殊字符

我正在尝试使用Java和SAX为Android设备解析XML文件。 我从互联网上获得,并解析它时,我得到一个ExpatException:对字符“é”没有格式良好(无效标记)。 有没有办法处理这些字符,而不必更改XML文件中的所有特殊字符?

编辑:这是我的代码写入我的SDcard文件的一部分。

File SDCardRoot = Environment.getExternalStorageDirectory();
            File f = new File(SDCardRoot,"edt.xml");
            f.createNewFile();
            FileOutputStream fileOutput = new FileOutputStream(f);
            InputStream inputStream = urlConnection.getInputStream();


            byte[] buffer = new byte[1024];
            int bufferLength = 0;
            while ( (bufferLength = inputStream.read(buffer)) > 0 ) {
                fileOutput.write(buffer, 0, bufferLength);
            }

            fileOutput.close();

这是我的xml的一部分:

<?xml version="1.0" encoding="iso-8859-1"?>
<?xml-stylesheet type="text/xsl" href="ttss.xsl"?>

<timetable>
<option combined="0" totalweeks="0" showemptydays="0" dayclass="reverse">
<link href="g56065.xml" class="xml">Imprimer</link>
<link href="g56065.pdf" class="pdf">Version PDF</link>
<weeks>Semaines</weeks>
<dates>Dates</dates>
<week>Semaine</week>
<date>Date</date>
<all>Toutes les semaines</all>
<notes>Remarques</notes>
<id>ID</id>
<tag>Champs Libre</tag>
<footer>Publié le 10/09/2011 22:14:28</footer>
... </timetable>

这里是解析代码:

public class ParserSemaines extends DefaultHandler {
    private final String SEMAINE = "span";
    private final String DESCRIPTION = "description";
    private ArrayList<Semaine> semaines;
    private boolean inSemaine;
    private Semaine currentSemaine;
    private StringBuffer buffer;
    @Override
    public void processingInstruction(String target, String data) throws SAXException {
        super.processingInstruction(target, data);
    }
    public ParserSemaines() {
        super();
    }

    @Override
    public void startDocument() throws SAXException {
        super.startDocument();
        semaines = new ArrayList<Semaine>();
    }

    @Override
    public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
        buffer = new StringBuffer();
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.currentSemaine = new Semaine();
            this.currentSemaine.setDate(attributes.getValue("date"));
            this.inSemaine = true;
        }
        if(localName.equalsIgnoreCase(DESCRIPTION)){
            this.currentSemaine.setDescription(buffer.toString());
        }
    }

    @Override
    public void endElement(String uri, String localName, String name) throws SAXException {
        if (localName.equalsIgnoreCase(SEMAINE)){
            this.semaines.add(currentSemaine);
            this.inSemaine = false;
        }
    }

    public void characters(char[] ch,int start, int length) throws SAXException{
        String lecture = new String(ch,start,length);
        if(buffer != null) buffer.append(lecture);
    }

    public ArrayList<Semaine> getData(){
        return semaines;
    }
}

这里是我用来调用解析器的代码:

SAXParserFactory fabrique = SAXParserFactory.newInstance();
        SAXParser parseur = null;
        ArrayList<Semaine> semaines = null;
        try {
            parseur = fabrique.newSAXParser();
            DefaultHandler handler = new ParserSemaines();
            File f = new File(Environment.getExternalStorageDirectory(),"edt.xml");
            parseur.parse(f, handler);  
            semaines = ((ParserSemaines) handler).getData();
        }

询问是否需要其他代码部分。

检查后,看起来SD卡中的xml文件显示“é”为“½”。 这应该是问题,但我不知道为什么。 我也尝试用URI解析,但它不会改变任何我总是得到相同的异常。


检查后,看起来SD卡中的xml文件显示“é”为“½”。

这确实表示编码问题。

您发布的代码似乎是从URL到文件的正确逐字节副本,因此该文件应该完全代表您从URL获得的内容。 这意味着来自服务器的响应可能不在ISO-8859-1中。

我的下一步将是使用诸如Fiddler这样的工具来检查整个反应,并特别注意:

  • Content-Type标头。 如果它告诉你一个不同的字符集,你必须将这些信息传递给解析器和/或手动转换它。
  • 实际返回的字节。 就你所知,内容类型和XML序言都可能在说谎。 如果文件是真正的ISO-8859-1,那么重音符号应该有一个字节值0xE9。 如果内容实际上是UTF-8,则应该有两个字节的序列0xC3 0xA9(请参阅此处)。 你正在显示一个三字节的序列,这是没有意义的。 但最好检查来源。
  • 另外,在将文件传递给SAX解析器之前,请验证您没有将该文件转换为字符串。


    作为参考:我编写了一个连接到OP的URL并将该连接直接传递给最小SAX解析器的最小程序。 它似乎运行没有错误。 我还使用了DOM解析器,并验证了至少根元素已被正确解析。

    public static void main(String[] argv)
    throws Exception
    {
       URL url = new URL("http://www.disvu.u-bordeaux1.fr/et/edt_etudiants2/Master/Semestre1/g56065.xml");
       InputStream in = url.openConnection().getInputStream();
    
       SAXParserFactory spf = SAXParserFactory.newInstance();
       SAXParser parser = spf.newSAXParser();
       parser.parse(in, new DefaultHandler());
       System.out.println("parse successful");
    }
    

    我终于找到解决方案。 我使用的不是使用SAXparder

    android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler);
    

    感谢大家为我提供的所有帮助。


    可能是编码问题。 尝试将其更改为ISO-8859-1

    在你的xml中尝试:

    <?xml version="1.0" encoding="ISO-8859-1"?>
    

    或者在您的代码中使用:

    inputSource.setEncoding("ISO-8859-1");
    
    链接地址: http://www.djcxy.com/p/34909.html

    上一篇: SAX handling special characters

    下一篇: Python SAX parser says XML file is not well