Ошибка синтаксического анализа 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);
Другие вопросы по тегам