【问题标题】:StreamException: An invalid XML character (Unicode: 0x1a)StreamException:无效的 XML 字符(Unicode:0x1a)
【发布时间】:2011-12-14 14:07:11
【问题描述】:

我正在使用 XStream 将用户对象保存在文件中。

private void store() {
    XStream xStream = new XStream(new DomDriver("UTF-8"));
    xStream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);

    xStream.alias("configuration", Configuration.class);
    xStream.alias("user", User.class);

    synchronized (ConfigurationDAOImpl.class) {
        try {
            xStream.toXML(configuration, new FileOutputStream(filename.getFile()));
        } catch (IOException e) {
            throw new RuntimeException("Failed to write to " + filename, e);
        }
    }
}

当我尝试通过以下代码读取它时,我得到一个异常:com.thoughtworks.xstream.io.StreamException: : 在文档的元素内容中发现了一个无效的 XML 字符 (Unicode: 0x1a)。

private void lazyLoad() {
    synchronized (ConfigurationDAOImpl.class) {
        // Has the configuration been loaded
        if (configuration == null) {
            if (filename.exists()) {
                try {
                    XStream xStream = new XStream(new DomDriver("UTF-8"));
                    xStream.setMode(XStream.XPATH_ABSOLUTE_REFERENCES);

                    xStream.alias("configuration", Configuration.class);
                    xStream.alias("user", User.class);

                    configuration = (Configuration) xStream
                            .fromXML(filename.getInputStream());

                    LOGGER.debug("Loaded configuration from {}.", filename);
                } catch (Exception e) {
                    LOGGER.error("Failed to load configuration.", e);
                }
            } else {
                LOGGER.debug("{} does not exist.", filename);
                LOGGER.debug("Creating blank configuration.");

                configuration = new Configuration();
                configuration.setUsers(new ArrayList<User>());

                // and store it
                store();
            }
        }
    }
}

有什么想法吗?

【问题讨论】:

标签: java xml


【解决方案1】:

0x1a 是无效的 xml 字符。无法在 xml 1.0 文档中表示它。

引自http://en.wikipedia.org/wiki/XML#Valid_characters

以下范围内的 Unicode 代码点在 XML 1.0 中有效 文档:[9] U+0009、U+000A、U+000D:这些是唯一的 C0 控件 在 XML 1.0 中接受; U+0020–U+D7FF, U+E000–U+FFFD:这不包括一些 BMP 中的(不是全部)非字符(所有代理项,U+FFFE 和 U+FFFF 被禁止); U+10000–U+10FFFF:这包括所有代码点 补充平面,包括非字符。

【讨论】:

  • 感谢您的回答。我通过一种方法将 0x1a 替换为破折号('-')。
【解决方案2】:

我通过以下方法将 0x1a 替换为破折号('-'):

/**
 * This method ensures that the output String has only
 * @param in the string that has a non valid character.
 * @return the string that is stripped of the non-valid character
 */
private String stripNonValidXMLCharacters(String in) {      
    if (in == null || ("".equals(in))) return null;
    StringBuffer out = new StringBuffer(in);
    for (int i = 0; i < out.length(); i++) {
        if(out.charAt(i) == 0x1a) {
            out.setCharAt(i, '-');
        }
    }
    return out.toString();
}

【讨论】:

  • 你应该已经接受了jontros的回答作为正确答案,他回答了你的问题并给出了很好的解释。
  • 认真接受另一个答案。有些版主会在这里生气。
  • 投了反对票,因为您应该接受 Jontro 的回答,而不是自己提出。
【解决方案3】:

正如已经指出的,XML 1.0 只接受一组符合this 的字符。

这是一个有用的 java 方法,可确保字符串符合 XML 1.0,它用给定的替换替换无效的 (所有这些都不仅仅是 0x1a)

public static String replaceInvalidXMLCharacters(String input, String replacement) {
        StringBuffer result = new StringBuffer();
        char currentChar;

        if (input == null || "".equals(input)) {
            return "";
        }
        for (int i = 0; i < input.length(); i++) {
            currentChar = input.charAt(i);
            if (currentChar == 0x9 || currentChar == 0xA || currentChar == 0xD || currentChar >= 0x20 && currentChar <= 0xD7FF || currentChar >= 0xE000
                    && currentChar <= 0xFFFD || currentChar >= 0x10000 && currentChar <= 0x10FFFF) {
                result.append(currentChar);
            } else {
                result.append(replacement);
            }
        }
        return result.toString();
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-10
    • 2013-09-10
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    • 2011-09-05
    • 1970-01-01
    • 2021-03-26
    相关资源
    最近更新 更多