首页 文章

读取用Java编写的UTF16编码的XML文件

提问于
浏览
1

我试图用Java读取UTF-16 xml文件 . 该文件是用C#编写的 .

这是java代码:

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

public class XMLReadTest
{
    public static void main(String[] s)
    {
        try
        {
            File fXmlFile = new File("C:\\my_file.xml");

            DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
            Document doc = dBuilder.parse(fXmlFile);

            doc.getDocumentElement().normalize();

            NodeList nList = doc.getElementsByTagName("row");

            for (int temp = 0; temp < nList.getLength(); temp++)
            {
                Node nNode = nList.item(temp);

                if (nNode.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element eElement = (Element) nNode;

                    System.out.println("FILE_NAME: " + eElement.getElementsByTagName("FILE_NAME").item(0).getTextContent());
                }
            }
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }
}

这是xml文件:

<?xml version="1.0" encoding="utf-16" standalone="yes"?>
<docMetadata>
  <row>
    <FILE_NAME>Выписка_Винтовые насосы.pdf</FILE_NAME>
    <FILE_CAT>GENERAL</FILE_CAT>
  </row>
</docMetadata>

在eclipse和Run / Debug设置窗口中运行此代码时,在名为“Common”的最后一个选项卡中,所选编码是Default - Inherited(Cp1253),我得到的输出是错误的:

文件名: ???????_???????? ?????? . PDF

当同一选项卡中的selecdted编码为UTF-8时,输出正常:

FILE_NAME:Выписка_Винтовыенасосы.pdf

我究竟做错了什么?

如何在eclipse项目设置中使用默认编码(cp 1253)获得正确的输出?

此代码在服务器中运行,我不想更改虚拟机的默认编码 .

我用Java 7和Java 8测试了这段代码

4 回答

  • 0

    这个问题与XML本身无关 . Java字符串是UTF-16编码的, Document 正确地将XML数据解码为UTF-16字符串 . 真正的问题是你将Eclipse设置为使用 cp1253 (Windows-1253希腊语,它与ISO-8859-7希腊语略有不同)作为其控制台字符集,但是你尝试输出的大多数Unicode字符(俄语)只是在那个charset中不存在,所以它们被替换为 ? . 这也解释了为什么当控制台字符集设置为UTF-8时输出是正确的,因为UTF8 < - > UTF16转换是无损的 .

  • 0

    尝试在输入流中显式设置编码:

    Document doc = dBuilder.parse(new InputStreamReader(new FileInputStream(fXmlFile), "UTF-16"));
    
  • 0

    如何在eclipse项目设置中使用默认编码(cp 1253)获得正确的输出?

    你不能 . 要查看正确的输出,控制台必须知道要显示的字符 .

    此代码在服务器中运行,我不想更改虚拟机的默认编码 .

    您可以编写一个UTF-8/16日志文件,您可以在其中使用另一个控制台或文本编辑器中的cat查看输出 .

    if (nNode.getNodeType() == Node.ELEMENT_NODE)
                {
                    Element eElement = (Element) nNode;
                    String message = "FILE_NAME: " + eElement.getElementsByTagName("FILE_NAME").item(0).getTextContent();
                    System.out.println(message);
                    // output FILE_NAME to logfile.txt (quick and dirty)
                    OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(new File("logfile.txt")), "UTF-8");
                    writer.write(message);
                    writer.close();
                }
    

    我在运行配置中使用ISO-8859-1编码在eclipse中运行此代码 .

    Eclipse输出:FILE_NAME:???????? ???????? ?????? . PDF

    日志文件输出:FILE_NAME:Выписка_Винтовыенасосы.pdf

  • 1

    我使用旧的dom4j库来解析xml,这导致了问题 . 使用JVM 1.7 embeded库解决了这个问题:

    import java.io.File;
    import java.io.StringReader;
    
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    
    import org.w3c.dom.Document;
    import org.w3c.dom.Element;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    import org.xml.sax.InputSource;
    
    public XMLDoc()
        {
            try
            {
                File xmlFile = new File("C:\\my_file.xml");
                DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
                DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
                Document doc = dBuilder.parse(xmlFile);
                doc.getDocumentElement().normalize();
    
                NodeList nList = _doc.getElementsByTagName("row");
                for (int i = 0; i < nList.getLength(); i++)
                {
                    Node nNode = nList.item(i);
    
                    if (nNode.getNodeType() == Node.ELEMENT_NODE)
                    {
                        Element eElement = (Element) nNode;
                        Node itemNode = eElement.getElementsByTagName("FILE_NAME").item(0);
                        String text = itemNode != null ? itemNode.getTextContent() : "";
    
                        // russian text is fine here
                    }
                }
            }
            catch(Exception e)
            {
                e.printStackTrace();
            }
        }
    

相关问题