我正在使用StAX创建XML文件,然后使用和XSD验证文件。
我在创建XML文件时遇到错误:
javax.xml.stream.XMLStreamException: Underlying stream encoding 'Cp1252' and input paramter for writeStartDocument() method 'UTF-8' do not match.
at com.sun.xml.internal.stream.writers.XMLStreamWriterImpl.writeStartDocument(XMLStreamWriterImpl.java:1182)
以下是代码段:
XMLOutputFactory xof = XMLOutputFactory.newInstance();
try{
XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileWriter(fileName));
xtw.writeStartDocument("UTF-8","1.0");} catch(XMLStreamException e) {
e.printStackTrace();
} catch(IOException ie) {
ie.printStackTrace();
}
我在Unix上运行此代码。有人知道如何设置版本和编码风格吗?
答案 0 :(得分:13)
我也会尝试将createXMLStreamWriter()
与输出参数一起使用。
[编辑]试过,它的工作原理是更改createXMLStreamWriter行:
XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileOutputStream(fileName), "UTF-8");
[编辑2]做了一个更复杂的测试,记录:
String fileName = "Test.xml";
XMLOutputFactory xof = XMLOutputFactory.newInstance();
XMLStreamWriter xtw = null;
try
{
xtw = xof.createXMLStreamWriter(new FileOutputStream(fileName), "UTF-8");
xtw.writeStartDocument("UTF-8", "1.0");
xtw.writeStartElement("root");
xtw.writeComment("This is an attempt to create an XML file with StAX");
xtw.writeStartElement("foo");
xtw.writeAttribute("order", "1");
xtw.writeStartElement("meuh");
xtw.writeAttribute("active", "true");
xtw.writeCharacters("The cows are flying high this Spring");
xtw.writeEndElement();
xtw.writeEndElement();
xtw.writeStartElement("bar");
xtw.writeAttribute("order", "2");
xtw.writeStartElement("tcho");
xtw.writeAttribute("kola", "K");
xtw.writeCharacters("Content of tcho tag");
xtw.writeEndElement();
xtw.writeEndElement();
xtw.writeEndElement();
xtw.writeEndDocument();
}
catch (XMLStreamException e)
{
e.printStackTrace();
}
catch (IOException ie)
{
ie.printStackTrace();
}
finally
{
if (xtw != null)
{
try
{
xtw.close();
}
catch (XMLStreamException e)
{
e.printStackTrace();
}
}
}
答案 1 :(得分:5)
这应该有效:
// ...
Writer writer = new OutputStreamWriter(new FileOutputStream(fileName), "UTF-8");
XMLStreamWriter xtw = xof.createXMLStreamWriter(writer);
xtw.writeStartDocument("UTF-8", "1.0");
// ...
答案 2 :(得分:2)
从代码中很难确定,但如果您依赖于JDK 1.6提供的默认Stax实现(Sun sjsxp),我建议升级以使用Woodstox。 众所周知,它比Sjsxp更少,支持整个Stax2 API,并且一直在积极开发和支持(而Sun版本只是编写而且修复的bug数量有限)。
但代码中的错误是:
XMLStreamWriter xtw = xof.createXMLStreamWriter(new FileWriter(fileName));
您依赖的是默认平台编码(必须是CP-1252,Windows?)。您应该始终明确指定您正在使用的编码。流编写器只是验证您没有做一些危险的事情,并发现可能导致文档损坏的不一致。非常聪明,这实际上表明这不是默认的Stax处理器。 : - )
(另一个答案指出了正确的解决方法,只需传递OutputStream和编码让XMLStreamWriter做正确的事情)
答案 3 :(得分:0)
如果使用与Oracle JRE / JDK捆绑在一起的默认XMLStreamWriter
,您应始终
XMLStreamWriter
,明确设置字符编码:xmlOutputFactory.createXMLStreamWriter(in, encoding)
xmlStreamWriter.writeStartDocument(encoding, version)
。编写器在创建编写器时记住编码集是不够聪明的。但是,它会检查这些编码是否相同。请参阅以下代码。这样,您的文件编码和XML声明始终保持同步。尽管在XML声明中指定编码是可选的,但XML最佳实践是始终指定它。
这是Oracle(Sun)实现的代码(Sjsxp):
String streamEncoding = null;
if (fWriter instanceof OutputStreamWriter) {
streamEncoding = ((OutputStreamWriter) fWriter).getEncoding();
}
else if (fWriter instanceof UTF8OutputStreamWriter) {
streamEncoding = ((UTF8OutputStreamWriter) fWriter).getEncoding();
}
else if (fWriter instanceof XMLWriter) {
streamEncoding = ((OutputStreamWriter) ((XMLWriter)fWriter).getWriter()).getEncoding();
}
if (streamEncoding != null && !streamEncoding.equalsIgnoreCase(encoding)) {
// If the equality check failed, check for charset encoding aliases
boolean foundAlias = false;
Set aliases = Charset.forName(encoding).aliases();
for (Iterator it = aliases.iterator(); !foundAlias && it.hasNext(); ) {
if (streamEncoding.equalsIgnoreCase((String) it.next())) {
foundAlias = true;
}
}
// If no alias matches the encoding name, then report error
if (!foundAlias) {
throw new XMLStreamException("Underlying stream encoding '"
+ streamEncoding
+ "' and input paramter for writeStartDocument() method '"
+ encoding + "' do not match.");
}
}