Ошибка синтаксического анализа XML, связанная с набором кодировок символов
У меня есть действительный файл XML (причина, по которой браузер может его проанализировать), который я пытаюсь проанализировать с помощью JDOM2. Код работал хорошо для других файлов XML, но для этого конкретного файла XML он дает мне следующее исключение в строке builder.build(): "com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException: Invalid byte 3 из 3-байтовой последовательности UTF-8. "
Мой код выглядит следующим образом
import java.io.*;
import java.util.*;
import java.net.*;
import org.jdom2.*;
import org.jdom2.input.*;
import org.jdom2.output.*;
import org.jdom2.adapters.*;
public class Test
{
public static void main(String st[])
{
String results="N.A.";
SAXBuilder builder = new SAXBuilder();
Document doc;
results = scrapeSite().trim();
try
{
doc = builder.build(new ByteArrayInputStream(results.getBytes()));
}
catch(JDOMException e)
{
System.out.println(e.toString());
}
catch(IOException e)
{
System.out.println(e.toString());
}
}
public static String scrapeSite()
{
String temp="";
try
{
URL url = new URL("http://msu-footprints.org/2011/Aditya/search_5.xml");
URLConnection conn = url.openConnection();
conn.setAllowUserInteraction(false);
InputStream urlStream = url.openStream();
BufferedReader br = new BufferedReader(new InputStreamReader(urlStream));
String t = br.readLine();
while(t!=null)
{
temp = temp + t;
t = br.readLine();
}
}
catch(IOException e)
{
System.out.println(e.toString());
}
return temp;
}
}
2 ответа
Почему вы читаете XML в строку с помощью Reader? Вы повреждаете XML, прежде чем анализировать его. обрабатывать xml как байты, а не символы.
и почему вы читаете весь URL InputStream только для того, чтобы преобразовать его в другой ByteArrayInputStream? Вы можете уменьшить это примерно до 2 строк кода, передав URL InputStream непосредственно разработчику. (не упоминать, чтобы избежать дополнительных проблем с памятью, вызванных чтением всего потока в память).
Как указывает jtahlborn, вы всегда должны рассматривать XML как байты, позволяя синтаксическому анализатору обрабатывать кодировку.
Но более того, вы никогда не должны использовать String.getBytes() для получения байтов строки: вы не получите то, что вы думаете.
В этом случае вы можете просто получить байты сайта, но даже если бы вы создавали XML в строке, а затем передавали его синтаксическому анализатору в виде последовательности байтов (или, что более вероятно, записывали байты в файл), вы бы хочу указать кодировку так, чтобы она соответствовала кодировке, в которой говорится в XML-коде, по умолчанию это UTF-8:
byte[] bytes = myString.getBytes("UTF-8");
Аналогично, если по какой-то причине вам нужно было использовать Writer или Reader, вы должны указать кодировку для записи или чтения.
Если вам нужно создать XML, хорошим способом является использование класса XMLStreamWriter:
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
XMLStreamWriter writer =
XMLOutputFactory.newInstance().createXMLStreamWriter(outStream);