Как проверить правильность данных XML в UTF-8 и обнаружить неправильные символы? - PullRequest
1 голос
/ 01 марта 2011

В моем приложении мне нужно проверить данные XML и забрать все недопустимые символы (поместить их в CDATA)

Мой вопрос довольно прост ... ^^ как это сделать?

Я начал с методов Character.UnicodeBlock, но как это работает с символами, инкорпорированными в несколько байтов - например, «ï» или «é»?

Это мой код на данный момент (для тестирования):

public static void main(String[] args) {

try {
    byte[] data = "J'ai prïé et `".getBytes("UTF-8");

    System.out.print("Data: ");
    for (int i = 0; i < data.length; i++) {
    System.out.print((char) data[i]);
    }

    System.out.println("");

    UnicodeBlock myBlock = null;

    for (int i = 0; i < data.length; i++) {
    System.out.println("[" + i + " => '" + (char) data[i]
        + "'] Is defined: "
        + Character.isDefined(new Byte(data[i]).intValue()));
    try {
        myBlock = Character.UnicodeBlock.of(new Byte(data[i])
            .intValue());
    } catch (IllegalArgumentException e) {
        System.out
            .println("Count => "
                + Character.charCount(new Byte(data[i])
                    .intValue()));
    }
    }
} catch (UnsupportedEncodingException e) {
    System.err.println("Unsupported encoding: " + e.getMessage());
}
System.out.println("Finished");
}

И вот что я получаю при исполнении:

Data: J'ai pr???? et `
[0 => 'J'] Is defined: true
[1 => '''] Is defined: true
[2 => 'a'] Is defined: true
[3 => 'i'] Is defined: true
[4 => ' '] Is defined: true
[5 => 'p'] Is defined: true
[6 => 'r'] Is defined: true
[7 => '?'] Is defined: false
Count => 1
[8 => '?'] Is defined: false
Count => 1
[9 => '?'] Is defined: false
Count => 1
[10 => '?'] Is defined: false
Count => 1
[11 => ' '] Is defined: true
[12 => 'e'] Is defined: true
[13 => 't'] Is defined: true
[14 => ' '] Is defined: true
[15 => '`'] Is defined: true
Finished

Я пытаюсь найти способ также обнаруживать несколько байтовых символов и иметь только «ложный» результат для реальногоневерные символы.

Может быть, библиотека на Java уже существует для этого?

Буду очень любезен, если кто-нибудь сможет мне помочь.Заранее спасибо.

С уважением.

1 Ответ

8 голосов
/ 01 марта 2011

Несколько вещей:

  • CDATA не защитит вас от недопустимых символов; Ваши ненужные данные все еще будут недопустимыми последовательностями UTF-8 и могут быть отклонены анализаторами XML
  • использовать сконфигурированный CharsetDecoder с InputStreamReader для проверки последовательности символов; альтернативно, проверки последовательности байтов действительны, проверяя их, как описано в RFC 2279 (см. определение UTF-8)
  • Я бы не стал разбирать XML без анализатора XML
  • Character.isDefined ожидает UTF-16BE в кодировке char ( или UTF-32BE в кодировке int), а не в кодировке UTF-8 байтов
  • в Java 6, Character.isDefined ограничено кодовыми точками, определенными в Unicode Standard, версия 4.0. ; могут существовать действующие документы UTF-8, определенные более поздними стандартами, для которых это не удастся (версия 6 уже вышла); последний список допустимых кодовых точек определен в UnicodeData.txt
...