看来,这种方法的行为在Java 8中发生了变化。 我需要一些快速解决我的问题。
问题在于我有一些代码在每个名为<row>
的XML节点之后编写CR和LF。现在(当我们迁移到Java 8时),而不是CR和LF,写出了字符
。
同样,我需要一个快速修复,我不能改变StaX实现或做那样大的事情。
while (reader.hasNext()){
event = reader.next();
if (event == XMLStreamConstants.START_ELEMENT){
if (reader.getLocalName().equals("row")){
writer.writeCharacters("\r\n"); /// this is my problem now!!!
writer.writeStartElement(reader.getLocalName());
n = reader.getAttributeCount();
for (int i=0; i<n; i++){
name = reader.getAttributeName(i).getLocalPart();
value = reader.getAttributeValue(i);
...
}
}
答案 0 :(得分:1)
您需要访问作为您使用XMLStreamWriter修饰的编写器的底层编写器(希望如果有一个它将是您传递给createXMLStreamWriter()
的编写者),或者您需要暂时禁用转义,这是依赖于实现。
你获得奇怪字符的原因是XMLStreamWriter不知道你在哪里写这些字符所以它默认为XML attribute escaping which is stricter than element (content) escaping。转义通常也基于CharacterEncoder
。我的猜测是,在旧版本的Java中,它默认为XML元素转义,它不会像换行符或使用不同的字符编码那样逃避空白区域。我可以看出为什么他们修复了这个问题,因为清楚属性转义是正确的方法。我也不知道你实际使用的是哪个XMLStreamWriter
或CharacterEncoder
,可能更可能发生的是默认选择的XMLStreamWriter或字符编码实现发生了变化(你应该在调试器中检查哪一个被选中)
无论您是否可以访问基础编写器,您都可以直接编写字符并且不会对其进行转义。但是请确保您使用的编写器是装饰的而不是更深的编写器(即,如果您有装饰FileWriter的BufferWriter使用BufferWriter)。
对于那些不会想writeCharacters does escaping you can look at the code的人。
修改强>
显然,在查看代码后,您可以在默认的sun impl上调用writer.setEscapeCharacters(false)
(很遗憾,您可能需要进行一些投射),然后再调用writeCharacters
这可能比获取原作者更好。
我不知道这面旗帜。
编辑2
如果您希望使用Sun StaX实现,那么另一种可能的快速修复方法是更改系统级字符编码并选择编码,以便CRLF不会理想地转移到JDK升级之前的状态。这假设问题可能是您的字符编码在Java升级时从Windows或ISO更改为UTF-8但我无法确定,因为您没有指定您的操作系统。如果它在升级时没有改变(即希望你总是默认为UTF-8),那么忽略这个选项。
编辑3
在做了一些测试后,我非常肯定你的StaX实现不是默认的Java Sun实现,但可能是Woodstox。我还没有对Woodstox进行过测试,但出于性能原因,它看起来很容易关注空白,如果它的UTF-8和ISO(再次是字符编码)似乎有不同的规则。
答案 1 :(得分:0)
我所做的修复只是调用以下方法。
writer.writeCharacters(System.lineSeparator());
工作正常并生成原始(而非XML转义)CR / LF数据 而且,事实证明我在Linux上遇到了问题,而在Windows上它运行正常。