Язык XML - практическое введение
9123a142

Решения и исправления


К счастью, всех этих проблем можно полностью избежать, используя парсер XML. Парсеры XML доступны во всех языках программирования (даже Cobol поддерживает XML), поэтому их безусловно стоит использовать.

У разработчика обычно есть две возможности: парсер XML или компонент преобразования. Если необходим контроль чтения документа XML низкого уровня, то лучше использовать парсер. Настоящий парсер XML является единственной гарантией того, что каждый документ XML будет правильно прочитан.

Если такой тщательный контроль, который обеспечивает парсер, не требуется, то компонент преобразования (такой как JAXB, Castor или Axis) может оказаться удобнее. Эти компоненты напрямую преобразуют тэги XML в объекты JavaTM. JAXB и Castor работают с документами в файлах, а Axis - с web-сервисами. Компоненты преобразования включают парсер XML, поэтому они полностью поддерживают синтаксис XML.

Хотя автор рекомендует использовать парсеры для чтения документов XML, он также признает, что этого можно избежать, если пользователь создает собственный способ для записи документов. Чтение документов XML - достаточно сложная задача, поскольку читающее программное обеспечение должно поддерживать полный синтаксис XML. Напротив, создание документов XML - это сравнительно более легкая процедура, поскольку можно использовать только часть синтаксических возможностей. Например, если пользователю не требуются атрибуты, то и не возникает необходимости в их поддержке; если не нужно многожество кодировок, то их также можно не поддерживать, и т.д.

Единственная опасность в этом подходе - это то, что нужно корректно передавать зарезервированные символы (см. табл. 1). Особое внимание нужно обращать на символы сущностей (например, i), поскольку они зависят от кодировки документа (см. раздел "Проблемы кодировки" ниже).

Таблица 1. Зарезервированные символы



Символ Управляющая последовательность Примечания
< <
& &
> >
' ' Только в атрибутах, если символ " используется как разделитель
" " Только в атрибутах, если символ ' используется как разделитель
другие &#unicode; Любой символ, не поддерживаемый данной кодировкой
<
br>
Обычно достаточно простого цикла, аналогичного приведенному в листинге 1. Данную функцию можно применять более эффективно, но листинг 1 синтаксически корректен, если документ создается для потока UTF-8 или UTF-16 (в противном случае необходимо также передать некоторые символы за счет использования символьных сущностей).
Листинг 1. Применение стандартного алгоритма избегания
// assumes UTF-8 or UTF-16 as encoding, public String escape(String content) { StringBuffer buffer = new StringBuffer(); for(int i = 0;i < content.length();i++) { char c = content.charAt(i); if(c == '<') buffer.append("<"); else if(c == '>') buffer.append(">"); else if(c == '&') buffer.append("&"); else if(c == '"') buffer.append("""); else if(c == '\'') buffer.append("'"); else buffer.append(c); } return buffer.toString(); }
Некоторые разработчики предпочитают использовать секции CDATA вместо управляющей последовательности. CDATA - это механизм, который показывает, что часть документа может содержать незаменяемые зарезервированные символы. Например: <condition>< ! [CDATA [a > 4] ] > < / condition>. Этот способ менее надежен, чем управляющая последовательность, т.к. одна секция CDATA не может включать другую такую же секцию.
В качестве еще одного решения автор рекомендует преобразователь (transformer), для чего предлагает познакомиться со своей статьей "Реализация XMLReader" (Implement XMLReader).

Содержание раздела