【问题标题】:String from Servlet with control characters in XML CDATA来自 Servlet 的字符串,带有 XML CDATA 中的控制字符
【发布时间】:2011-09-23 07:40:53
【问题描述】:

我的问题类似于Why are "control" characters illegal in XML 1.0? - 但是我正在寻找以下问题的解决方案,而不是为什么 XML 规范不允许 XML 中的控制字符。

我有一个 servlet,它根据用户请求打印一个包含 XML 的字符串。一个特定元素包含一个 CDATA 部分,该部分需要包含一些用户输入文本。

现在碰巧在一种特殊情况下,我们的用户输入包含字符 U+0001(一个控制字符)。即使我将字符集指定为 UTF-8,servlet 也会抛出错误:

Error: not well-formed
Location: 

<![CDATA[ 

有没有一种方法可以处理 Java 字符串以使其“XML 安全”?尤其是放在 CDATA 部分时要保证安全?

希望我的问题很清楚!

提前致谢, 拉杰

【问题讨论】:

    标签: java xml servlets utf-8 unicode-string


    【解决方案1】:

    使这种 XML 安全的唯一符合方法是添加您自己的编码。

    你可以做这两个之一(例如):

    • 将所有数据存储为文本数据,并用某种 unicode-escape 机制(XML 本身定义的机制除外!)替换所有禁用字符。例如,您可以使用 Java 使用的那个:\u0001 表示 U+0001。
    • 将数据存储为二进制数据并使用base64BinaryhexBinary 以XML 格式存储您的数据。

    这两种方法都需要消费者生产者的明确支持。第二种方法的优点是使用具有广泛支持的定义明确的数据类型,但如果您的内容实际上是文本,则需要指定(或传达)字节流中使用的编码(否则 XML 本身会否定这一必要性) )。

    如果删除所有non-transferable characters是合适的,那么这个正则表达式应该可以解决问题:

    Pattern XML_INVALID_CHARS = Pattern.compile("[^\u0009\n\r\u0020-\uD7FF\uE000-\uFFFD\uD800\uDC00-\uDBFF\uDFFF ]+");
    String xmlSafe = XML_INVALID_CHARS.matcher(input).replaceAll("");
    

    请注意,规范建议文档作者对注释中允许的字符集更加严格。那个正则表达式会更长一些。

    【讨论】:

    • 感谢绍尔的快速响应。我希望会有一些第三方 API 接受一个字符串并返回一个字符串,其中非 XML 安全字符被清除。叹息!
    • @Raj:那么简单地删除有问题的字符是可以接受的吗?这可能会容易得多......
    • 绍尔,是的,这对我来说会更好。但我不想删除空格和换行符等控制字符。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2012-04-12
    • 2021-07-29
    • 1970-01-01
    • 2012-12-18
    相关资源
    最近更新 更多