Практична робота з XML: Досвід безпечного написання документів та програм. Частина 1 (вихідні коди)

На основі власного досвіду участі в проектах XML автор склав список проблем, які найбільш часто зустрічаються при використанні цієї технології. Читач може істотно знизити ризик зробити помилку, знаючи заздалегідь про ці проблеми. У даній статті автор розглядає потенційні проблеми самої мови XML.


Протягом останніх семи років автору крупно щастило – він мав унікальну можливість стежити за розвитком і становленням мови XML, і все завдяки своїй роботі в якості консультанта, викладача та письменника.


Коли XML був представлений публіці вперше, організації та розробники поставилися до цього нового мови розмітки з ввічливим підозрою. Але в міру того як вони використовували цю мову для рішення все більшого числа проблем, підозрілість змінилася ентузіазмом. Сьогодні вже дуже багато розробників і організації використовують XML у своїх проектах.


На жаль, разом із зростаючою популярністю виникли і проблеми, пов'язані з неправильним застосуванням XML. У цьому відношенні процес впровадження XML не відрізняється від впровадження інших технологій. Перші користувачі будь-якої нової технології зазвичай є її ентузіастами (і вони повинні бути такими, якщо хочуть переконати колег і споживачів у перевагах цієї технології). Але у них також можуть бути і сумніви, тому вони зазвичай намагаються вивчити, як краще всього впроваджувати нову технологію.


У міру розвитку технології вона все більше сприймається як належне. І, відповідно, чим ширше використовується технологія з різними додатками, тим більше здійснюється помилок. На щастя, одночасно накопичується і досвід роботи з цією технологією, і з'являються перевірені рішення для найбільш часто виникаючих проблем. Ці рішення документуються, так само як і найбільш поширені проблеми.


Для цієї серії з чотирьох статей, я переглянув свої записи і відшукав найбільш часто зустрічаються "пастки" в XML. Я сподіваюся, що задокументувавши їх і представивши альтернативи, я допоможу вам подолати основні перешкоди технології.


Я почну з фундаментального -, власне, з XML.Пріверженность загальноприйнятій синтаксису – це перший крок на шляху створення надійних додатків. Нижче розглядаються наступні загальні питання:



Следующии статті розглянуть, як використовувати XML-документи напевно, як перевіряти і тестувати XML-документи і як сопрячь XML з багатьма іншими файловими форматами, такими як зображення, фільми, текст і т.д.


Простий синтаксис


У першому розділі обговорюються деякі загальні питання синтаксису XML.


Синтаксис XML досить простий: просто необхідно дотримуватися балансу між відкривають і закривають тегами. Проте автор дуже хотів би отримувати знаменитий п'ятицентовика щоразу отримуючи електронне лист, відправник якого нарікає на те, що йому не вдалося обробити доданий до листа документ XML жодним з відомих йому парсерів. Незмінно при відкритті надісланого документа XML автор виявляє очевидну синтаксичну помилку – порожній тег без закриває косою риси (наприклад: <empty/>). Якщо в документі не дотримуються всі правила синтаксису XML, то він не є документом XML і, отже, не може бути оброблений за допомогою інструментів XML. Синтаксис XML дуже точний і формальний. Всі дуже просто: або в документі дотримуються всі правила синтаксису XML, або він не може бути розпізнаний як документ XML.


Але деякі програми можуть відмовлятися працювати з абсолютно точно допустимими документами. Такі програми можуть реалізовувати синтаксис XML не повністю і, відповідно, бути нездатним розпізнати деякі символьні сутності (наприклад, î).


Проблема полягає в простоті, що здається XML. Часто здається, що простіше і швидше щось прибрати, ніж вивчити якийсь новий компонент. Такий підхід може працювати в замкнутому циклі, коли програма має справу з документом, створений самим цим додатком. Але в промисловій експлуатації, коли документ обробляється декількома додатками, цей підхід вже навряд чи виявиться успішним.


Рішення та виправлення


На щастя, всіх цих проблем можна повністю уникнути, використовуючи парсер XML. Парсери XML доступні у всіх мовах програмування (навіть Cobol підтримує XML), тому їх безумовно варто використовувати.


У розробника зазвичай є дві можливості: парсер XML або компонент перетворення. Якщо необхідний контроль читання документа XML низького рівня, то краще використовувати парсер. Для цілей цієї статті, неважливо який парсер ви будете використовувати – DOM, JDOM, SAX, or StAX, – але тільки справжній парсер XML є єдиною гарантією того, що кожен документ XML буде правильно прочитаний.


Якщо такий ретельний контроль, який забезпечує парсер, не потрібно, то компонент перетворення (такий як JAXB, Castor або Axis) може виявитися зручніше. Ці компоненти безпосередньо перетворять теги XML в об'єкти Java ™. JAXB і Castor працюють з документами у файлах, а Axis – з web-сервісами. Компоненти перетворення включають парсер XML, тому вони повністю підтримують синтаксис XML.


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


Єдина небезпека в цьому підході – це те, що потрібно коректно передавати зарезервовані символи (див. табл. 1). Особливу увагу потрібно звертати на символи сутностей (наприклад, î) Оскільки вони залежать від кодування документа (див. розділ "Проблеми кодування" нижче).


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
































Символ 

Керуюча послідовність 

Примітки 

< <  
& &  
> >  
' Тільки в атрибутах, якщо символ "використовується як розділювач
Тільки в атрибутах, якщо символ "використовується як розділювач
other &#unicode; Будь-який символ, який не підтримується даним кодуванням


Зазвичай достатньо простого циклу, аналогічного наведеному в лістингу 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 у третій статті серії, але на даний момент варто сказати, що цей спосіб менш надійний, ніж керуюча послідовність, тому що одна секція CDATA не може включати іншу таку ж секцію.


У якості більш гнучкого рішення використовуйте перетворювач (transformer) – загляньте в мою підказку – "Інструмент XMLReader," на developerWorks.


Ще один спосіб виправлень


Уявімо ситуацію, що користувачеві необхідно працювати з додатком, який не зовсім відповідає синтаксису XML, і він не може переконати розробника виправити цей додаток.


Автор пропонує звертатися з такими додатками не як з додатками XML і включає додаткову стадію для конвертації документів цих програм в ці документи XML. Ця процедура необхідна для того, щоб усунути невідповідності та використовувати будь-які інструменти XML для подальшої обробки.


Проблеми кодування


Більш серйозні проблеми можуть виникнути при використанні різних кодувань. Розробники часто випускають з уваги той факт, що кодування не обмежують той набір символів, який підтримує XML. Будь-який документ XML підтримує повний набір символів Unicode (16 – або 32-бітові символи в XML 1.1).


Використання кодувань в документі XML може скоротити його розмір, але при цьому, завдяки наявності символьних сутностей, в ньому можуть виявитися не тільки символи Unicode. За допомогою цих символів можна вставити будь-яку літеру з таблиці Unicode, навіть якщо в документі використовується найбільш сувора кодування (US-ASCII, яка підходить тільки для чотирьох мов – англійської, гавайського, латинського і суахілі).


Це дійсно проблема, оскільки якщо програми Java або остання версія DB2 ® можуть підтримувати Unicode, то більш ранні додатки майже не здатні на це. Таким чином, якщо документ XML передається в "старе" додаток, доведеться зіткнутися з Unicode. Відповідно, використання кодувань не є рішенням, оскільки, як показано вище, завжди можна уникнути спеціальних символів за рахунок символьних сутностей.


Оскільки переписування старого програми рідко використовується як рішення проблеми, необхідний спосіб конвертації, який перетворить символи Unicode в набір, прийнятний для програми: наприклад, конвертація "Î" в звичайну "i" (тобто прибирання діакритичних знаків). Більшість парсерів XML мають можливості для обробки символів Unicode.


Проблеми простору імен


Третє джерело проблем, який обговорюється в цьому пункті, – це використання просторів імен XML.


Простору імен були введені для управління словниками XML і запобігання використання тегів з однаковими іменами. Часто два словники можуть використовувати один і той же тег у різних контекстах. Наприклад, в словнику повідомлень можуть бути теги для теми, дати, відправника, адресата і тіла листа (див. лістинг 2), а в словнику цифрових ресурсів – теги для теми, дати, описи, камери і номери кадру (див. лістинг 3).


Лістинг 2. Словник повідомлень





<envelope>
<subject>Test memo</subject>
<date>April 26, 2005</date>
<from>jack@writeit.com</from>
<to>john@xmli.com</to>
<body>memo body goes here</body>
</envelope>


Лістинг 3. Словник цифрових ресурсів





<photo>
<subject> Westlicht Museum of Camera and Photography, Vienna </ subject>
<date>April 25, 2005</date>
<description>Lobby of the museum</description>
<camera>Nikon D70</camera>
<frame>5643</frame>
</photo>

Конфлікти виникають, якщо цифровий ресурс посилається через платформу для обміну повідомленнями, оскільки програмне забезпечення не може відрізнити один від одного теги теми і дати в двох словниках. Іншими словами, ім'я тега не є глобальним ідентифікатором.


Простору імен XML перетворюють локальні імена в глобальні шляхом додавання глобального ідентифікатора до імені тега. Для того щоб гарантувати унікальність глобальних ідентифікаторів, вони повинні представляти собою URI (Uniform Resource Identifiers – універсальні ідентифікатори ресурсів) (тобто містити ім'я домену, зареєстрованого для гарантії унікальності). Відповідний приклад приведений в лістингу 4.


Лістинг 4. Поєднання словників





<env:envelope xmlns:env=”http://psol.com/2005/env”
xmlns:ph=”http://psol.com/2005/photo”>
<env:subject>Latest photo</env:subject>
<env:date>April 27, 2005</env:date>
<env:from>jack@writeit.com</env:from>
<env:to>john@xmli.com</env:to>
<env:body>
<ph:photo>
<ph:subject>Westlicht Museum
of Camera and Photography, Vienna </ ph: subject>
<ph:date>April 25, 2005</ph:date>
<ph:description> Lobby of the museum </ ph: description>
<ph:camera>Nikon D70</ph:camera>
<ph:frame>5643</ph:frame>
</ph:photo></env:body>
</env:envelope>

Тут є два моменти, які вимагають додаткових пояснень:



URI і адреси


Хоча на практиці більшість URI є адресами (URL – Uniform Resource Locators – уніфіковані покажчики інформаційних ресурсів), в просторі імен XML вони використовуються лише як ідентифікатори. На жаль, простору імен не можуть ідентифікуватися так само, як пакети Java. Наприклад: com.psol.vocabulary замість більш невизначеного http://psol.com/vocabulary.


Оскільки URI є ідентифікаторами, адреси можуть не працювати, тобто видавати помилку "404 – Resource not found" – при спробі відкрити їх. Але вони виконують необхідні від них функції. І, всупереч широко поширеній помилці, URI просторів імен не вказують на схему XML Консорціуму всесвітньої мережі (World Wide Web Consortium – W3C).


По-друге, оскільки в цьому контексті URI є ідентифікаторами, додаток повинен точно, до букви, відповідати їх написання. Було б помилкою використовувати URI словника XML для вказівки, наприклад, на свій сервер. Наприклад, URI для XSL виглядає наступним чином: http://www.w3.org/1999/XSL/Transform. Якщо користувач працює в IBM, він не може перетворити цей URI в, наприклад, такий: http://www.ibm.com/1999/XSL/Transform. Насправді зміни URI існуючих словників не допускаються взагалі.


Коли я проводив заняття, присвячені XSLT, студенти часто дивувалися, чому в нього / неї процесор XSLT не працює – насправді, причина була тільки в тому, що XSLT URI не був відтворений правильно.


Перший висновок з вищевикладеного матеріалу – необхідно утримуватися від зміни просторів імен.Включеніе схеми версії в URI зазвичай не є хорошою ідеєю, оскільки це напевно "зламає" додатка при виконанні оновлень (і так, я усвідомлюю, що саме це й зробила W3C з SOAP).


Префікси


Ще одна загальна помилка – плутанина між префіксами і ідентифікаторами. Префікс не є ідентифікатором з тієї ж причини, з якої їм не може бути ім'я тега: дуже великий ризик, якщо два різних додатка використовують одні і той же префікс. Тому префікси просторів імен прозорі, і ними не можна маніпулювати в додатках. Але для творця документа XML цілком допустимо змінювати префікси в документі (наприклад, для уникнення конфліктів).


Приклади неправильного і правильного кодів наведено в лістингах 5 і 6, відповідно.


Лістинг 5. Некоректна перевірка префіксів





startElement (String uri, String local, String qname, Attributes atts)
{
if(qname.equals(“env:Envelope”))
; // do something
}


Лістинг 6. Коректна перевірка URI простору імені





startElement (String uri, String local, String qname, Attributes atts)
{
if(uri.equals(“http://psol.com/2005/envelope”)
&& local.equals(“Envelope”))
; // do something
}

Висновок


Отже, якщо користувач знає про всі потенційні небезпеки і помилки, описаних вище, то він може істотно поліпшити створювані їм документи і додатки XML. Більш того, це дає можливість звести до мінімуму ризик несумісності і помітно спростити підтримку додатків XML.


Схожі статті:


Сподобалася стаття? Ви можете залишити відгук або підписатися на RSS , щоб автоматично отримувати інформацію про нові статтях.

Коментарів поки що немає.

Ваш отзыв

Поділ на параграфи відбувається автоматично, адреса електронної пошти ніколи не буде опублікований, допустимий HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

*