与char编码集相关的XML解析错误

时间:2013-02-15 00:17:13

标签: java character-encoding xml-parsing jdom-2

我有一个有效的XML文件(有效的原因浏览器可以解析它),我尝试使用JDOM2进行解析。代码对其他xml文件运行良好但是对于这个特定的xml文件,它在builder.build()行上给出了以下异常:“com.sun.org.apache.xerces.internal.impl.io.MalformedByteSequenceException:无效的字节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 个答案:

答案 0 :(得分:1)

为什么要用读取器将xml读入String?在解析之前,你正在破坏xml。将xml视为字节,而不是字符。

为什么要读取整个URL InputStream只是为了将其转换为另一个ByteArrayInputStream?您可以通过将URL InputStream直接传递给构建器来将其减少到大约2行代码。 (不提及避免因将整个流读入内存而导致的额外内存问题。)

答案 1 :(得分:0)

正如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);