SAX处理特殊字符

时间:2011-09-13 13:54:10

标签: java sax

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

编辑: 这是我的代码将文件写入SD卡的部分。

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解析但它没有改变任何东西,我总是得到同样的异常。

3 个答案:

答案 0 :(得分:1)

  

检查后,SD卡中的xml文件显示“é”为“�”。

这确实表明存在编码问题。

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

我的下一步是使用Fiddler之类的工具来检查整个响应,特别注意:

  • Content-Type标头。如果它告诉您不同的字符集,则必须将该信息传递给解析器和/或手动转换它。
  • 返回的实际字节数。尽管如此,两者 Content-Type和XML序言都可能在撒谎。如果文件是真正的ISO-8859-1,则重音e的字节值应为0xE9。如果内容实际上是UTF-8,则应该有两个字节的序列0xC3 0xA9(参见here)。您正在显示一个三字节序列,这没有意义。但最好检查来源。

另外,在将文件传递给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");
}

答案 1 :(得分:1)

我终于找到了解决方案。 我使用

而不是使用SAXparder
android.util.Xml.parse(InputStream,Xml.Encoding.ISO_8859_1, DefaultHandler);

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

答案 2 :(得分:0)

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

在xml中尝试:

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

或者,在您的代码中,使用:

inputSource.setEncoding("ISO-8859-1");
相关问题