【发布时间】:2011-11-16 05:06:33
【问题描述】:
我正在尝试使用 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 进行解析,但它并没有改变任何东西,我总是遇到同样的异常。
【问题讨论】:
-
SAX 解析器应该可以毫无问题地处理非 ASCII 字符。显示您的代码和 XML 示例。
-
听起来像:1. XML 文件编码不正确,或 2. XML 文件在 Internet 上正确提供,其字符编码由 HTTP 标头指示,并且您在保存时丢失了该信息本地文件。
-
显示的代码只是将数据复制为原始字节,因此不能以任何方式与 XML 编码混淆。您需要显示解析代码。
-
请在您设置实际 SAX 解析器的位置添加代码(即,从解析器工厂获取解析器并调用 parse())。
-
你的解析代码看起来很好,这表明服务器给你的内容不正确。