Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/399.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用Java将XML文档从Latin1转换为UTF8_Java_Xml_Character Encoding - Fatal编程技术网

使用Java将XML文档从Latin1转换为UTF8

使用Java将XML文档从Latin1转换为UTF8,java,xml,character-encoding,Java,Xml,Character Encoding,我正在尝试创建一个XML文档(rss提要),并且已经解决了其中的所有问题,除了一个字符编码问题。问题是我使用的是UTF-8编码,就像这样,除了文档本身没有编码为UTF-8之外 我正在使用org.apache.ecs.xml包创建所有标记。然后我使用doc.output(stream)来编写内容。这种方法似乎不使用UTF-8编写输出,我不知道如何实现这一点。在我这么做之前,一些符号(我第一次注意到的是英镑)在大多数读者中并没有得到正确的呈现 --更新了更多信息-- 我最终使用了一个糟糕的解决方案(

我正在尝试创建一个XML文档(rss提要),并且已经解决了其中的所有问题,除了一个字符编码问题。问题是我使用的是UTF-8编码,就像这样
,除了文档本身没有编码为UTF-8之外

我正在使用org.apache.ecs.xml包创建所有标记。然后我使用
doc.output(stream
)来编写内容。这种方法似乎不使用UTF-8编写输出,我不知道如何实现这一点。在我这么做之前,一些符号(我第一次注意到的是英镑)在大多数读者中并没有得到正确的呈现

--更新了更多信息--


我最终使用了一个糟糕的解决方案(如评论中所解释的)来解决这个问题。正确答案似乎是不要使用org.apache.ecs.xml库。谢谢大家的帮助。StackOverflow再次获胜。

我不熟悉此软件包,但从网上的来源来看,我怀疑它可能已损坏:

包含像这样的内容

        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

for(int i=0;i这是我编写的一个函数,用于将所有非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();
}
因此,这些字符也将转换为相应的Unicode实体。
这会将我所有的PCDATA转换为unicode友好的ASCII字符串。自从使用此技术以来,我再也没有编码问题。我从未输出过未通过此方法传递的XML PCDATA:这并不是在掩盖事实。它只是通过尽可能通用的方式来解决问题。

Simpleest解决方案可能会更改您的代码,如下所示:

XMLDocument doc = new XMLDocument(1.0,false,Charset.defaultCharset().toString());
我猜他们只是在使用默认编码向流中写入字符。因此,将默认编码传递到序言中,您就可以了

我同意其他海报的说法,这可能是你最不担心的。看看for ECS,它似乎已经四年没有更新了(“ECS2”存储库也是如此)


还有一些自我提升:如果你想用一个简单的界面来构建XML文档,那么这个库有一个生成器。它使用标准的JDK序列化机制进行输出。

你可以向编写器而不是输出流进行写操作……这样你就可以指定编码。

我的同事提出了一个解决方案我认为这是正确的方法,但我知道什么。我们没有使用
doc.output(stream)

try { IOUtils.write(doc.toString(), stream, "UTF-8"); } catch (IOException e) { throw new RuntimeException(e); } 试一试{ 写入(doc.toString(),流,“UTF-8”); }捕获(IOE异常){ 抛出新的运行时异常(e); }
老实说,我还没有完全理解这个问题,这就是为什么我首先遇到问题的原因。似乎@Subtenant的解决方案通过并转换了UTF-8无法表示的任何字符,并将其替换为unicode实体。这个解决方案似乎像我原来一样使用UTF-8编码写入流ly想要doc.output to。我不知道确切的区别,只是两者都解决了我的问题。如果有任何进一步的评论来帮助我理解这个问题,我将不胜感激。

请提供一个代码示例,说明如何使用
org.apache.ecs.xml
包,以及如何准备
doc
对象。哦,天哪……那英镑在哪里来自?GUI控制?命令行?内联代码?您的问题/格式很酷,不必担心,也很受欢迎!问题不在提供的信息和代码中。乍一看,一切都很好。问题最有可能出现在
OutputStream
参数中。它来自何处?在噢,也可能是feedItems本身已经包含了错误的字符。这些字符来自哪里?请调查/调试它。确保您的调试工具(IDE?)本身正在使用UTF-8!不幸的是,我确实看到了这一点,但我希望有某种解决方法。无论如何,感谢您的软件包建议。
Charset.defaultCharset()
返回特定于平台的默认字符集,该字符集可能与XML文件编码不同和/或根本不是Unicode派生,例如
CP-1252
(哎哟)或者
ISO-8859-x
。你不想这样。你之前需要知道XML文件的实际编码。如果你仔细阅读这个问题,你会发现OP实际上在生成XML文件,而不是消费XML文件。如果你仔细阅读我的回答,你会发现我使用XML文件的理由序言中的
defaultEncoding()
似乎是第三方库(雅加达ECS)使用它。这解决了错误的问题。他需要对输出流进行UTF-8编码,这与用字符实体替换非ascii数据非常不同。这些字符实体仍将指向拉丁1代码点,而不是必需的UTF-8代码点。正如Jim所写(和我的同事向我指出的)这只是为了掩盖问题。这成了我的临时解决方案,只是因为我需要一个快速解决方案,但当我有时间的时候,我会回去重写我的代码,因为它完全错了。哈哈,太棒了。我对迄今为止唯一能带来一些东西的答案投了反对票。我爱你们朋友。@Jim:我知道我没有以期望的方式回答这个问题是的。如果有人提出了更好的解决方案,我很乐意升级它并在我自己的代码中使用它。到目前为止,清理PCDATA一直是我的最佳方法,在所有情况下都有效。@UmYeah:当您只有ASCII字符时,您的文本是UTF-8编码的。您只是改变了扩展字符的引用方式。您允许客户有责任格式化这些字符。@Jim:“这些字符实体仍将指向拉丁1代码点,而不是必需的UTF-8代码poi try { IOUtils.write(doc.toString(), stream, "UTF-8"); } catch (IOException e) { throw new RuntimeException(e); }