Строка из сервлета с управляющими символами в XML CDATA - PullRequest
2 голосов
/ 27 июня 2011

Мой вопрос похож на Почему «управляющие» символы недопустимы в XML 1.0? - однако я ищу решение приведенной ниже проблемы, а не почему спецификация XML запрещает управляющие символы в XML .

У меня есть сервлет, который печатает строку, содержащую XML, по запросу пользователя. Один конкретный элемент содержит раздел CDATA, который должен содержать некоторый текст, вводимый пользователем.

Теперь так получилось, что в одном конкретном случае наш пользовательский ввод содержит символ U + 0001 (управляющий символ). И хотя я указываю кодировку как UTF-8, сервлет выдает ошибку:

Error: not well-formed
Location: 

<![CDATA[ 

Есть ли способ, которым я могу обработать строку Java, чтобы сделать ее "безопасной для XML"? В частности, чтобы сделать его безопасным при установке в разделе CDATA?

Надеюсь, мой вопрос ясен!

Спасибо заранее, Радж

1 Ответ

2 голосов
/ 27 июня 2011

Единственный подходящий способ сделать этот XML-безопасный - это добавить свою собственную кодировку.

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

  • Сохранить все данныев качестве текстовых данных и замените все запрещенные символы каким-либо механизмом экранирования Unicode (кроме того, который определен в самом XML!).Например, вы можете использовать тот, который используется в Java: \u0001 для U + 0001. или
  • сохраните данные в виде двоичных данных и используйте base64Binary из hexBinary для хранения ваших данных в XML.

Оба этих подходов нуждаются в явной поддержке как потребителя , так и производителя.Второй подход имеет преимущество использования четко определенных типов данных с широкой поддержкой, но если ваш контент на самом деле является текстовым, вам нужно указать (или сообщить) кодировку, используемую в потоке байтов (необходимость, которая в противном случае отрицается самим XML).).

Если удалить все непередаваемые символы , то это регулярное выражение должно выполнить трюк:

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("");

Обратите внимание, чтоспецификация предлагает , чтобы авторы документов были еще более строгими с набором символов, разрешенных в заметке.Это регулярное выражение будет немного длиннее.

...