Parser SAX không thể phân tích cú pháp XML UTF-8 ?
Ngày xưa, parser XML JDK Apache Xerces được tích hợp sẵn sẽ thông báo lỗi Invalid byte 1 of 1-byte UTF-8 sequence nếu chúng ta cố gắng phân tích cú pháp tệp XML có chứa các ký tự UTF-8.
Ví dụ, một tệp XML chứa một ký hiệu đặc biệt và hai ký tự Trung Quốc.
<?xml version="1.0"?>
<company>
<staff>
<firstname>sharecs</firstname>
<lastname>木金</lastname>
<nickname>§</nickname>
<salary>100000</salary>
</staff>
</company>
Và chúng ta sử dụng Parser SAX để xử lý tệp XML ở trên.
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
PrintAllHandlerSax handler = new PrintAllHandlerSax();
saxParser.parse("c://test//staff.xml", handler);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
Kết quả:
com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException:
Invalid byte 1 of 1-byte UTF-8 sequence.
Mã hóa ký tự trong XML
Nếu tệp XML bị thiếu mã hóa, trình phân tích cú pháp sẽ mặc định thành UTF-8.
<?xml version="1.0"?>
<company>
<staff>
<firstname>sharecs</firstname>
<lastname>木金</lastname>
<nickname>§</nickname>
<salary>100000</salary>
</staff>
</company>
Cách tốt nhất là xác định mã hóa ký tự cho tệp XML.
<?xml version="1.0" encoding="utf-8"?>
<company>
<staff>
<firstname>sharecs</firstname>
<lastname>木金</lastname>
<nickname>§</nickname>
<salary>100000</salary>
</staff>
</company>
Mã hóa ký tự trong mã nguồn
Mã hóa ký tự không chính xác sẽ gây ra Invalid byte 1 of 1-byte UTF-8 sequence. Ví dụ: chúng ta đọc dữ liệu XML bằng UTF-8, nhưng nó là kiểu mã hóa khác ISO_8859_1.
Để khắc phục, chúng ta có thể xác định mã hóa ký tự cho Parser SAX.
package com.sharecs.xml.sax;
import com.sharecs.xml.sax.handler.PrintAllHandlerSax;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ReadXmlSaxParser {
//private static final String FILENAME = "src/main/resources/staff.xml";
private static final String FILENAME = "c://test//staff.xml";
public static void main(String[] args) {
SAXParserFactory factory = SAXParserFactory.newInstance();
try {
SAXParser saxParser = factory.newSAXParser();
PrintAllHandlerSax handler = new PrintAllHandlerSax();
//saxParser.parse(FILENAME, handler);
XMLReader xmlReader = saxParser.getXMLReader();
xmlReader.setContentHandler(handler);
InputSource source = new InputSource(FILENAME);
// different encoding
source.setEncoding(StandardCharsets.UTF_8.displayName());
xmlReader.parse(source);
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
}
Cảm ơn các bạn đã ghé thăm. Chúc các bạn thành công!