В настоящее время я пишу класс util для sanitize input, который сохраняется в xml-документе.Санитарная обработка для нас означает, что все недопустимые символы (https://en.wikipedia.org/wiki/Valid_characters_in_XML#XML_1.0) просто удалены из строки.
Я попытался сделать это, просто используя некоторое регулярное выражение, которое заменяет все недопустимые символы пустой строкой,но для символов юникода вне BMP это, кажется, как-то нарушает кодировку, оставляя меня с этими ?
символами. Также не имеет значения, какой способ замены использовать регулярное выражение (String#replaceAll(String, String)
, Pattern#compile(String)
, org.apache.commons.lang3.RegExUtil#removeAll(String, String)
)
Вот пример реализации с тестом (в Spock), который показывает проблему: XmlStringUtil.java
package com.example.util;
import lombok.NonNull;
import java.util.regex.Pattern;
public class XmlStringUtil {
private static final Pattern XML_10_PATTERN = Pattern.compile(
"[^\\u0009\\u000A\\u000D\\u0020-\\uD7FF\\uE000-\\uFFFD\\x{10000}-\\x{10FFFF}]"
);
public static String sanitizeXml10(@NonNull String text) {
return XML_10_PATTERN.matcher(text).replaceAll("");
}
}
XmlStringUtilSpec.groovy
package com.example.util
import spock.lang.Specification
class XmlStringUtilSpec extends Specification {
def 'sanitize string values for xml version 1.0'() {
when: 'a string is sanitized'
def sanitizedString = XmlStringUtil.sanitizeXml10 inputString
then: 'the returned sanitized string matches the expected one'
sanitizedString == expectedSanitizedString
where:
inputString | expectedSanitizedString
'' | ''
'\b' | ''
'\u0001' | ''
'Hello World!\0' | 'Hello World!'
'text with emoji \uD83E\uDDD1\uD83C\uDFFB' | 'text with emoji \uD83E\uDDD1\uD83C\uDFFB'
}
}
Теперь у меня есть решение, в котором я перестраиваю всю строку из отдельных кодовых точек, но это не похоже на правильное решение.
Заранее спасибо!