Этому вопросу восемь лет, и он до сих пор не совсем правильный ответ! Нет, вам не нужно импортировать весь сторонний API для выполнения этой простой задачи. Плохой совет.
Следующий метод будет:
- правильно обрабатывать символы вне базовой многоязычной плоскости
- экранирующие символы, необходимые в XML
- экранирование любых символов, не относящихся к ASCII, что необязательно, но обычно
- заменить недопустимые символы в XML 1.0 на символ замены Unicode. Здесь нет лучшего варианта - их удаление также верно.
Я пытался оптимизировать работу для наиболее распространенного случая, в то же время гарантируя, что вы можете передать / dev / random через это и получить правильную строку в XML.
public static String encodeXML(CharSequence s) {
StringBuilder sb = new StringBuilder();
int len = s.length();
for (int i=0;i<len;i++) {
int c = s.charAt(i);
if (c >= 0xd800 && c <= 0xdbff && i + 1 < len) {
c = ((c-0xd7c0)<<10) | (s.charAt(++i)&0x3ff); // UTF16 decode
}
if (c < 0x80) { // ASCII range: test most common case first
if (c < 0x20 && (c != '\t' && c != '\r' && c != '\n')) {
// Illegal XML character, even encoded. Skip or substitute
sb.append("�"); // Unicode replacement character
} else {
switch(c) {
case '&': sb.append("&"); break;
case '>': sb.append(">"); break;
case '<': sb.append("<"); break;
// Uncomment next two if encoding for an XML attribute
// case '\'' sb.append("'"); break;
// case '\"' sb.append("""); break;
// Uncomment next three if you prefer, but not required
// case '\n' sb.append(" "); break;
// case '\r' sb.append(" "); break;
// case '\t' sb.append("	"); break;
default: sb.append((char)c);
}
}
} else if ((c >= 0xd800 && c <= 0xdfff) || c == 0xfffe || c == 0xffff) {
// Illegal XML character, even encoded. Skip or substitute
sb.append("�"); // Unicode replacement character
} else {
sb.append("&#x");
sb.append(Integer.toHexString(c));
sb.append(';');
}
}
return sb.toString();
}
Редактировать: для тех, кто продолжает настаивать на том, что глупо писать свой собственный код для этого, когда есть совершенно хорошие Java API для работы с XML, вам может быть полезно знать, что StAX API включен в Oracle Java 8 ( Я не проверял других) не в состоянии правильно кодировать содержимое CDATA: он не экранирует]]> последовательности в содержимом. Сторонняя библиотека, даже та, которая является частью ядра Java, не всегда является лучшим вариантом.