为了账号安全,请及时绑定邮箱和手机立即绑定

处理 xml 文件时的 UTF8 编码无效

处理 xml 文件时的 UTF8 编码无效

jeck猫 2022-07-06 18:40:51
我有一个处理 XML 文件以读取一些值的 Java 代码。我收到一个错误:无效的 UTF8 编码,我试图将文件内容复制到 NotePad++ 上的另一个文件中,该过程运行良好,但如果我只将文件另存为其他名称,则会给出相同的错误。抱歉,我不能把我的 XML 文件放在这里,因为它太大了,我只会放 header 和 trailer。感谢您提供任何帮助来解决此错误。我处理 xml 文件的 java 代码:XPathFactory f=XPathFactory.newInstance();    XPath x=f.newXPath();    InputSource source=new InputSource(new FileInputStream("C:\\Users\\cc\\eclipse-workspace\\data\\file.xml") );    InputSource source2=new InputSource(new FileInputStream("C:\\Users\\cc\\eclipse-workspace\\data\\file.xml") );    XPathExpression trlr=x.compile("pers/trailer/text()");    XPathExpression hdr=x.compile("pers/header/CD/text()");    String s=trlr.evaluate(source);    String s2=hdr.evaluate(source2);    System.out.println("header :"+s+" trailer"+s2);pers 是 xml 文件中的根标记:XML 文件如下所示:<?xml version = '1.0' encoding = 'UTF-8'?><pers> <header>555</header> . . . . <trailer>666</trailer></pers>
查看完整描述

2 回答

?
智慧大石

TA贡献1946条经验 获得超3个赞

使用 java 编写脚本来检测有问题的行。


AtomicInteger lineno = new AtomicInteger();

Path path = Paths.get("... .xml");

Files.lines(path, StandardCharsets.ISO_8859_1)

    .forEach(line -> {

        int no = lineno.incrementAndGet();

        byte[] b = line.getBytes(StandardCharsets.ISO_8859_1);

        try {

            new String(b, StandardCharsets.UTF_8);

        } catch (Exception e) {

            System.out.printf("[%d] %s%n%s%n", no, line, e.getMessage());

            //throw new IllegalStateException(e);

        }

    });

人们可能会认为这是一个数据错误。


一般来说,它也可能是错误的缓冲读取:当一个多字节序列在缓冲区边界上被破坏时;然后可能会出现两个错误的半序列。在标准库代码中不太可能。


为了确保代码new String(...)不会被 JVM 丢弃,可能:


int sowhat = Files.lines(path, StandardCharsets.ISO_8859_1)

    .mapToInt(line -> {

        int no = lineno.incrementAndGet();

        byte[] b = line.getBytes(StandardCharsets.ISO_8859_1);

        try {

            return new String(b, StandardCharsets.UTF_8).length();

        } catch (Exception e) {

            System.out.printf("[%d] %s%n%s%n", no, line, e.getMessage());

            throw new IllegalStateException(e); // Must throw or return int

        }

    }).sum();

System.out.println("Ignore this: " + sowhat);

人们可能会认为这是一个数据错误。


一般来说,它也可能是错误的缓冲读取:当一个多字节序列在缓冲区边界上被破坏时;然后可能会出现两个错误的半序列。在标准库代码中不太可能。


为了确保代码new String(...)不会被 JVM 丢弃,可能:


int sowhat = Files.lines(path, StandardCharsets.ISO_8859_1)

    .mapToInt(line -> {

        int no = lineno.incrementAndGet();

        byte[] b = line.getBytes(StandardCharsets.ISO_8859_1);

        try {

            return new String(b, StandardCharsets.UTF_8).length();

        } catch (Exception e) {

            System.out.printf("[%d] %s%n%s%n", no, line, e.getMessage());

            throw new IllegalStateException(e); // Must throw or return int

        }

    }).sum();

非法的 XML 字符(在 1.0 版中)?[#x1-#x8] | [#xB-#xC] | [#xE-#x1F] | [#x7F-#x84] | [#x86-#x9F]


int sowhat = Files.lines(path, StandardCharsets.ISO_8859_1)

    .mapToInt(line -> {

        int no = lineno.incrementAndGet();

        byte[] b = line.getBytes(StandardCharsets.ISO_8859_1);

        if (!legal(b)) {

            System.out.printf("[%d] %s%n%s%n", no, line, e.getMessage());

            throw new IllegalStateException(e); // Must throw or return int

        }

    }).sum();


static boolean legal(byte[] bytes) {

    String s = new String(bytes, StandardCharsets.UTF_8);

    for (char ch : s.toCharArray()) {

        int x = ch;

        if ((0 <= x && x <= 8)               // ASCII control chars

                || (0xB <= x && x <= 0xC)

                || (0xE <= x && x <= 0x1F)

                || (0x7f <= x && x <= 0x84)  // DEL + Unicode control chars

                || (0x86 <= x && x <= 0x9F)) {

            return false;

        }

    }

    return true;

}

如果这不起作用,我已经让你足够长的时间了。拆分文件并验证零件。


查看完整回答
反对 回复 2022-07-06
?
守着一只汪

TA贡献1872条经验 获得超3个赞

我使用此代码将文件转换为 UTF-8 格式:


 File source = new File("C:\\Users\\cc\\eclipse-workspace\\data\\file.xml");

    String srcEncoding="ISO-8859-1";

    File target = new File("C:\\Users\\cc\\eclipse-workspace\\data\\file2.xml");

    String tgtEncoding="UTF-8";

      try (

        BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(source), srcEncoding));

        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(target), tgtEncoding)); ) {

            char[] buffer = new char[16384];

            int read;

            while ((read = br.read(buffer)) != -1)

                bw.write(buffer, 0, read);


  }


查看完整回答
反对 回复 2022-07-06
  • 2 回答
  • 0 关注
  • 303 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信