我有一个有效的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;
}
}
答案 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);