我正在尝试创建一个XML文档(rss feed)并解决了其中的所有问题,除了一个字符编码问题。问题是我使用的是像<?xml version="1.0" encoding="UTF-8"?>
这样的UTF-8编码,除了文档本身没有编码为UTF-8。
我正在使用org.apache.ecs.xml包来创建所有标签。然后我使用doc.output(stream
)来编写内容。这种方法似乎不使用UTF-8编写输出,我不知道如何实现这一点。在我做之前,一些符号(英镑是我第一次注意到的)在大多数读者中都没有正确呈现。
- 更新了更多信息 -
我最终使用了一个糟糕的解决方案(如评论中所述)来解决这个问题。正确的答案似乎是不要使用org.apache.ecs.xml库。谢谢大家的帮助。 StackOverflow再次获胜。
答案 0 :(得分:1)
最简单的解决方法可能是更改您的代码,如下所示:
XMLDocument doc = new XMLDocument(1.0,false,Charset.defaultCharset().toString());
我猜他们只是使用默认编码将字符写入流。所以将默认编码传递给序言,你应该没问题。
我同意其他海报,这可能是你最不担心的事情。查看ECS的source repository,它似乎没有更新四年(同样是“ECS2”存储库)。
还有一些自我推销:如果您希望使用简单的界面构建XML文档,Practical XML库就有一个构建器。它使用标准的JDK序列化机制进行输出。
答案 1 :(得分:1)
你有可能写入Writer而不是OutputStream ......你可以用这种方式指定编码。
答案 2 :(得分:1)
这是我的同事提出的解决方案,我认为这是正确的方法,但我知道什么。而不是使用我们使用的doc.output(stream)
:
try { IOUtils.write(doc.toString(), stream, "UTF-8"); } catch (IOException e) { throw new RuntimeException(e); }
说实话,我还没有完全理解这个问题,这就是我首先遇到问题的原因。似乎@ subtenante的解决方案经历并转换了UTF-8无法表示的任何字符,并将其替换为unicode实体。这个解决方案似乎使用UTF-8编码写入流,就像我最初想要doc.output一样。我不知道确切的区别,只是两个都解决了我的问题。任何进一步的评论,以帮助我理解这个问题将不胜感激。
答案 3 :(得分:0)
我不熟悉这个软件包,但是从网上的来源我怀疑它可能会被破坏:
http://kickjava.com/src/org/apache/ecs/xml/XMLDocument.java.htm
包含
之类的内容 for (int i=0; i<prolog.size(); i++) {
268 ConcreteElement e = (ConcreteElement)prolog.elementAt(i);
269 e.output(out);
270 // XXX really this should use line separator!
271 // XXX should also probably check for pretty print
272 // XXX also probably have difficulties with encoding
表明存在问题。
我们使用XOM(http://www.xom.nu),并且在其Serializer上专门有一个setEncoding(),所以我建议更改包...
答案 4 :(得分:0)
这是我写的一个函数,用于将所有非ASCII字符转换为相应的实体。可能会帮助您在输出之前清理一些PCDATA内容。
/**
* Creates xml entities for non ascii characters in the given String.
*/
public static String xmlEntitify(String in){
StringBuffer b = new StringBuffer();
for (int i=0;i<in.length();i++){
Character c = in.charAt(i);
if (c<128){
b.append(c);
}
else if (c=='\ufeff'){
// BOM character, just remove it
}
else {
String cstr = Integer.toHexString(c).toUpperCase();
while(cstr.length()<4){
cstr="0"+cstr;
}
b.append("&#x");
b.append(cstr);
b.append(";");
}
}
return b.toString();
}
将您的输入流读入String content
,然后写入输出流xmlEntitify(content)
。
您的输出保证仅包含ASCII字符,不再存在编码问题。
<强>更新强>
鉴于这些评论,我会更加大胆:如果你没有对你的数据进行消毒,你就会遇到麻烦。我想你至少已经取代了PCDATA中的<
和&
个字符。如果没有,你肯定应该。我有上述方法的另一个版本,而不是第一个if
,它有:
if (c<128 && c!='&' && c!='<' && c!='>' && c!='"'){
b.append(c);
}
这样这些字符也会转换为相应的Unicode实体。 这会将我的所有PCDATA转换为unicode友好的仅ASCII字符串。因为我正在使用这种技术,所以我没有更多的编码问题。我没有输出没有通过这种方法传递的XML PCDATA:这不是将大象扫到地毯下面。它只是通过尽可能通用来摆脱这个问题。