Java XML分析错误:prolog中不允许包含内容

Java XML分析错误:prolog中不允许包含内容,java,xml,parsing,utf-8,Java,Xml,Parsing,Utf 8,我的代码使用LSSerializer类编写XML文件: DOMImplementation impl = doc.getImplementation(); DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS","3.0"); LSSerializer ser = implLS.createLSSerializer(); String str = ser.writeToString(doc); Syste

我的代码使用LSSerializer类编写XML文件:

DOMImplementation impl = doc.getImplementation();
DOMImplementationLS implLS = (DOMImplementationLS) impl.getFeature("LS","3.0");

LSSerializer ser = implLS.createLSSerializer();

String str = ser.writeToString(doc);
System.out.println(str);

String file = racine+"/"+p.getNom()+".xml";
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
out.write(str);
out.close();
XML是格式良好的,但是当我解析它时,我得到了一个错误

解析代码:

File f = new File(racine+"/"+filename);

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(f);

XPathFactory xpfactory = XPathFactory.newInstance();
XPath xp = xpfactory.newXPath();

String expression;

expression = "root/nom";        
String nom = xp.evaluate(expression, doc);
错误:

[Fatal Error] Terray.xml:1:40: Content is not allowed in prolog.
9 août 2011 19:42:58 controller.MakaluController activatePatient
GRAVE: null
org.xml.sax.SAXParseException: Content is not allowed in prolog.
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:249)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:208)
at model.MakaluModel.setPatientActif(MakaluModel.java:147)
at controller.MakaluController.activatePatient(MakaluController.java:59)
at view.ListePatientsPanel.jButtonOKActionPerformed(ListePatientsPanel.java:92)
...
现在,经过一些研究,这个错误是由于XML开头的一个隐藏字符造成的

事实上,我可以通过手动创建一个XML文件来修复这个错误

但是XML编写中的错误在哪里呢?当我试图在字符串中打印时,前面没有空格 解决方案:更改序列化程序 我运行了UTF-16编码的解决方案一段时间,但它不是很稳定。 因此我找到了一个新的解决方案:更改XML文档的序列化程序,使编码在XML头和文件编码之间保持一致:

    DOMSource domSource = new DOMSource(doc);
    TransformerFactory tf = TransformerFactory.newInstance();
    Transformer transformer = tf.newTransformer();

    String file = racine+"/"+p.getNom()+".xml";
    OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");

    transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
    transformer.setOutputProperty(OutputKeys.INDENT,"yes");
    transformer.transform(domSource, new StreamResult(out));
但是XML编写中的错误在哪里呢

看起来错误不在写入中,而是在解析中。正如您已经发现的,文件开头有一个空白字符,这会导致stach跟踪中的解析调用出错:

Document doc = builder.parse(f);
打印时看不到空格的原因可能只是您使用的编码。尝试更改此行:

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");
使用“UTF-16”或“US-ASCII”

但是XML编写中的错误在哪里呢

看起来错误不在写入中,而是在解析中。正如您已经发现的,文件开头有一个空白字符,这会导致stach跟踪中的解析调用出错:

Document doc = builder.parse(f);
打印时看不到空格的原因可能只是您使用的编码。尝试更改此行:

OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(file),"UTF-8");

要使用“UTF-16”或“US-ASCII”

我认为它可能与BOM字节顺序标记有关。看


您可以通过示例使用Notepad++进行验证:打开您的文件并检查编码菜单,查看您使用的是不带BOM的UTF8还是带BOM的UTF8。

我认为它可能链接到BOM字节顺序标记。看


您可以通过以下示例使用Notepad++进行验证:打开文件并检查编码菜单,查看您是使用UTF8而不使用BOM,还是使用UTF8而不使用BOM。

使用UTF-16是一种方法

 OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(fileName),"UTF-16");

使用UTF-16读取文件时不会出现任何问题

 OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(fileName),"UTF-16");
这可以读取没有问题的文件

请尝试以下代码:

InputStream is = new FileInputStream(file);
Document doc = builder.parse(is , "UTF-8");
请尝试以下代码:

InputStream is = new FileInputStream(file);
Document doc = builder.parse(is , "UTF-8");

要确认这一点,请使用十六进制编辑器查看输入。不久前,我遇到了同样的问题,解决方法是先消耗BOM字节,然后再将数据提供给验证解析器。要检查的字节是:0xEF、0xBB、0xBFAh、神秘:使用UTF-8选项,我得到一个AINSI文件;使用UTF-16选项,我得到一个UTF16编码的文件!要确认这一点,请使用十六进制编辑器查看输入。不久前,我遇到了同样的问题,解决方法是先消耗BOM字节,然后再将数据提供给验证解析器。要检查的字节是:0xEF、0xBB、0xBFAh、神秘:使用UTF-8选项,我得到一个AINSI文件;使用UTF-16选项,我得到一个UTF16编码的文件!对解决方案:使用UTF-16编码。奇怪,是的!!解决方案:使用UTF-16编码。奇怪,你也看到了