Появление технологии Asynchronous JavaScript + XML (Ajax) вызвало новую волну энтузиазма в разработке Web-приложений, а также пересмотр многими разработчиками и проектировщиками своих методик создания Web-приложений. JavaScript Object Notation (JSON) представляет собой формат обмена данными, используемый для представления данных в бизнес-логику, выполняющуюся в браузерах. Многие Ajax-разработчики предпочитают обрабатывать данные напрямую, используя JSON в JavaScript-коде на стороне браузера. По мере расширения применения JSON в программах, работающих на серверах промежуточного уровня, станет необходимым предоставлять данные корпоративных приложений в браузеры в формате JSON, а не в XML-формате. Это означает, что разработчики должны преобразовать существующие корпоративные данные на стороне сервера, закодированные в XML-формате, в JSON-формат перед передачей их в браузер. В данной статье демонстрируется использование основанных на PHP серверных программ для преобразования данных приложения из XML-формата в JSON-формат.
XML - это стандарт для разметок. Основанная на XML разметка используется для описания данных, представляемых при помощи тегов, которые не обязательно должны быть определены заранее. XML очень хорошо расширяем, поскольку можно создавать новые теги по мере необходимости. В листинге 1 показан пример структуры данных, представленных в XML-формате.
Листинг 1. Простой пример XML-данных
<?xml version="1.0" encoding="UTF-8"?>
<contacts>
<contact id="1">
<name>John Doe</name>
<phone>123-456-7890</phone>
<address>
<street>123 JFKStreet</street>
<city>Any Town</city>
<state>Any State</state>
<zipCode>12345</zipCode>
</address>
</contact>
</contacts>
|
Первая строка - это XML-объявление, указывающее версию XML и используемую кодировку символов. Затем следует корневой элемент <contacts>, который охватывает несколько дочерних элементов. Вложенная структура дочерних элементов определяет данные для контакта. Обратите внимание на то, что элемент <address> содержит дочерние элементы, формирующие структуру поддерева ниже элемента <contact>. XML также позволяет указывать в открывающих тегах атрибуты, предоставляющие дополнительную информацию об элементах. Элемент <contact> имеет атрибут, присваивающий идентификатор этому элементу. XML-документ завершается закрывающим тегом </contacts> для корневого элемента.
JSON не является языком разметки, как XML. Это текстовый формат обмена данными. Используется синтаксис JavaScript-объектов и массивов. В двух словах, JSON позволяет предоставлять данные просто. Например, объекты заключаются в фигурные скобки ({}), массивы в квадратные ([]). Фрагмент JavaScript-кода может без труда принять закодированные в JSON данные без выполнения какой-либо специального синтаксического анализа или дополнительного преобразования данных. В листинге 2 приведена структура данных, представленная в JSON-формате.
Листинг 2. Простой пример JSON-данных
{
"contacts" : {
"contact" : {
"@attributes" : {
"id" : "1"
},
"name" : "John Doe",
"phone" : "123-456-7890",
"address" : {
"street" : "123 JFK Street",
"city" : "Any Town",
"state" : "Any State",
"zipCode" : "12345"
}
}
}
}
|
Можно заметить, что каждый фрагмент данных, показанный в XML-формате в листинге 1, также присутствует в JSON-примере в листинге 2. Однако различие заключается в том, как JSON кодирует данные, используя типы данных JavaScript - объекты и массивы. Структура данных начинается с объекта, содержащего свойство с именем "contacts", которое само по себе является объектом. Этот объект имеет одно свойство с названием "contact", которое тоже является объектом. Этот объект содержит несколько свойств, формирующих детали контакта. Обратите внимание на то, что объект "contact" содержит другой (вложенный) объект "address", который описывает детали адреса. Как и в XML, данные в JSON-формате описывают сами себя, поэтому их может легко прочитать как человек, так и машина.
Обработка данных на стороне браузера
Теперь давайте рассмотрим, как данные обрабатываются в коде, выполняющемся на стороне браузера. Когда сервер передает XML-данные в браузер, эти XML-данные обрабатываются с использованием Document Object Model (DOM) API. Однако JavaScript-разработчики должны изучить все тонкости XML-обработки и написать много дополнительного кода для синтаксического разбора XML-данных, прежде чем с ними можно будет что-либо сделать. С появлением JSON код на стороне сервера может спакетировать и передать данные приложения в JSON-формате в ответ на запрос браузера. Если код на стороне сервера передает данные в JSON-формате в браузер, JavaScript-разработчикам не нужно писать какую-либо дополнительную сложную логику для синтаксического разбора XML. Кроме этого, полученные в JSON-формате данные будут готовы для обработки в коде на стороне браузера как родная для JavaScript структура данных. Фрагмент кода, приведенный в листинге 3, показывает, что для обработки данных в JSON-формате не нужна дополнительная работа.
Листинг 3. Фрагмент кода для обработки данных в JSON-формате, полученных от сервера
var result = httpRequest.responseText;
jsonResponse = eval('(' + result + ')');
|
Во фрагменте кода, выполняющегося на стороне браузера и приведенного в листинге 3, result - это строка в JSON-формате, полученная от сервера. Все что требуется - одна строка кода для преобразования этих строковых данных в родной для JavaScript тип данных путем использования выражения eval. Можно заметить, что работать с JSON-данными на стороне браузера намного проще. Использование JSON привносит простоту и смысл в код на стороне браузера.
Выражение eval в листинге 3 будет выполняться независимо от того, что возвратит сервер, поэтому здесь имеет место риск нарушения системы защиты. Этот риск ограничен, поскольку политика системы защиты браузера ограничивает HTTP-запросы в JavaScript только тем сервером, с которого код был первоначально загружен. Но все-таки в некоторых ситуациях было бы благоразумно проверить получаемые от сервера данные на соответствие ожидаемым (возможно, с использованием регулярных выражений) перед передачей их в выражение eval.
Все большее количество приложений нуждается в преобразовании XML-данных в JSON. Несколько Web-сервисов, выполняющих такие преобразования, уже появились. IBM T.J. Watson Research Center разработал особый метод, использующий PHP для выполнения преобразования. Этот метод принимает XML-данные на входе и преобразует их в JSON-формат на выходе. Такое PHP-решение обеспечивает несколько преимуществ:
- Его можно запускать в автономном режиме, из командной строки.
- Его можно включить в существующий код, выполняющийся на стороне сервера.
- Его можно легко разместить как Web-сервис в Web.
Преобразование XML-в-JSON требует использования двух базовых функциональных возможностей PHP:
-
SimpleXMLElement - Services_JSON с http://pear.php.net (подробности приведены в разделе "Ресурсы")
SimpleXMLElement поддерживается в PHP версии 5 и выше. Это объект со свойствами, содержащими данные, хранимые в XML-документе. Services_JSON - это предложение с открытым исходным кодом (появившееся в конце 2005), реализуемое на PHP. Оно предоставляет функции JSON-кодирования (PHP-данные в JSON) и декодирования (JSON в PHP-данные). Эта библиотека PHP-классов с открытым исходным кодом в настоящее время доступна на Web-сайте PEAR (см. раздел "Ресурсы").
Используя только эти две базовые функциональные возможности PHP, можно преобразовать любые произвольные XML-данные в JSON-формат. Прежде всего, нужно преобразовать XML-содержимое в подходящий PHP-тип данных, используя SimpleXMLElement. Затем PHP-данные предоставляются в кодировщик Services_JSON, который, в свою очередь, формирует окончательный вывод данных в JSON-формате.
Данная реализация xml2json состоит из трех частей:
- xml2json.php - PHP-класс с двумя статическими функциями.
- xml2json_test.php - Тестовый драйвер для работы с функцией преобразования
xml2json. - test1.xml, test2.xml, test3.xml, test4.xml - XML-файлы различной сложности.
Для простоты в данной статье не приводятся подробные комментарии в исходном коде. Однако исходный код в поставляемых со статьей файлах содержит полные комментарии. Обращайтесь к этим исходным файлам за подробной информацией о логике работы программы (см. раздел "Загрузка").
В листинге 4 определяются некоторые полезные константы. Первая строка кода импортирует реализацию Services_JSON.
Листинг 4. Определение констант в xml2json.php
require_once 'json/JSON.php';
// Внутренний параметр Debug, специфичный для программы.
define ("DEBUG", false);
// Максимальная глубина рекурсии, которую мы можем позволить.
define ("MAX_RECURSION_DEPTH_ALLOWED", 25);
// Пустая строка.
define ("EMPTY_STR", "");
// Имя свойства объекта SimpleXMLElement для атрибутов.
define ("SIMPLE_XML_ELEMENT_OBJECT_PROPERTY_FOR_ATTRIBUTES", "@attributes");
// Имя объекта SimpleXMLElement.
define ("SIMPLE_XML_ELEMENT_PHP_CLASS", "SimpleXMLElement");
|
Фрагмент кода, приведенный в листинге 5, представляет собой входную функцию в преобразователь xml2json. Она принимает в качестве входного параметра XML-данные и преобразует XML-строку в объект SimpleXMLElement, который передается в другую функцию (рекурсивно) в данном классе. Эта функция преобразует XML-элементы в ассоциативный PHP-массив. Данный массив затем передается в качестве входного параметра в кодировщик Services_JSON, который выдает данные в JSON-формате.
Листинг 5. Использование Services_JSON в xml2json.php
public static function transformXmlStringToJson($xmlStringContents) {
$simpleXmlElementObject = simplexml_load_string($xmlStringContents);
|
Длинный фрагмент кода, приведенный в листинге 6, использует методологию рекурсии, разработанную PHP-сообществом сторонников открытого кода (см. раздел "Ресурсы"). Он принимает объект SimpleXMLElement в качестве входного параметра и рекурсивно проходит по вложенному XML-дереву. Он сохраняет все обнаруженные XML-элементы в ассоциативном PHP-массиве. Вы можете настроить предельную глубину рекурсии, изменив константу, определенную в листинге 4.
Листинг 6. Логика преобразования в xml2json.php
public static function convertSimpleXmlElementObjectIntoArray($simpleXmlElementObject,
&$recursionDepth=0) {
// Следить за глубиной рекурсии.
|
В конце успешного прохождения по XML-дереву эта функция преобразует и сохранит все XML-элементы (корневой элемент и все дочерние элементы) в ассоциативном PHP-массиве. Для сложных XML-документов получаемый PHP-массив будет таким же сложным. После завершения формирования этого PHP-массива кодировщик Services_JSON может легко преобразовать его в данные JSON-формата. Чтобы понять логику рекурсии, просмотрите документированный исходный файл.
Реализация тестового драйвера для xml2json
Фрагмент кода, приведенный в листинге 7, представляет собой тестовый драйвер, применяющий логику преобразования xml2json.
Листинг 7. xml2json_test.php
<?php
require_once("xml2json.php");
|
Вы можете выполнить программу из командной строки с именем XML-файла, указанным как аргумент командной строки:
php -f xml2json_test.php test2.xml |
При выполнении из командной строки программа читает XML-содержимое из файла в строковую переменную. Затем она вызывает статическую функцию в классе xml2json для получения результата в JSON-формате. Кроме выполнения программы из командной строки вы можете изменить логику в этом исходном файле для предоставления преобразователя xml2json в виде вызываемого Web-сервиса, использующего протоколы доступа Simple Object Access Protocol (SOAP) или Representational State Transfer (REST). При необходимости можно легко сделать это в PHP с минимальными затратами.
В листинге 8 приведен один из четырех тестовых XML-файлов, поставляемых со статьей для тестирования реализации xml2json. Степень сложности этих файлов различна. Вы можете передать один из этих файлов в виде аргумента командной строки в тестовый драйвер xml2json_test.php.
Листинг 8. Тестирование реализации xml2json с test2.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="1">
<title>Code Generation in Action</title>
<author><first>Jack</first><last>Herrington</last></author>
<publisher>Manning</publisher>
</book>
|
Фрагмент кода, приведенный в листинге 9, представляет собой результат в формате JSON при использовании файла test2.xml в качестве аргумента командной строки для тестового драйвера xml2json_test.php.
Листинг 9. Результат в JSON-формате для test2.xml
{
"books" : {
"book" : [ {
"@attributes" : {
"id" : "1"
},
"title" : "Code Generation in Action",
"author" : {
"first" : "Jack", "last" : "Herrington"
},
"publisher" : "Manning"
}, {
"@attributes" : {
"id" : "2"
},
"title" : "PHP Hacks", "author" : {
"first" : "Jack", "last" : "Herrington"
},
"publisher" : "O'Reilly"
}, {
"@attributes" : {
"id" : "3"
},
"title" : "Podcasting Hacks", "author" : {
"first" : "Jack", "last" : "Herrington"
},
"publisher" : "O'Reilly"
}
]}
}
|
Обратите внимание на то, что XML-атрибут id для элемента <book> сохраняется в JSON-данных как свойство объекта "@attributes", а элемент <book> сохраняется как массив объектов. Полученные данные в JSON-формате готовы для приема в JavaScript-коде с использованием выражения eval.
JSON только начинает приобретать вес среди Web-разработчиков. Его преимущества, видимые главным образом JavaScript-разработчиками, состоят в элегантности и простоте. В определенных ситуациях JSON может быть достойной альтернативой XML. В данной статье аргументируется необходимость преобразования XML-в-JSON на сервере промежуточного уровня. Затем внимание уделяется логическому обоснованию использования корпоративных данных в XML-формате в виде данных в формате JSON, для того чтобы программы на стороне браузера могли легко использовать их. Предоставляется PHP-код, который может выполнять преобразование XML-в-JSON (см. раздел "Загрузка").
Вы можете использовать исходный код, поставляемый с данной статьей, в различных целях - как автономную программу, как библиотеку классов для существующей программы, выполняющейся на стороне сервера, либо как функцию Web-сервиса SOAP/REST для участия в корпоративной сервис-ориентированной архитектуре (Service-Oriented Architecture - SOA).
| Описание | Имя | Размер | Метод загрузки |
|---|---|---|---|
| PHP-код для xml2json | x-xml2json_php.zip | 14KB | HTTP |
Научиться
- Оригинал статьи "Convert XML to JSON in PHP".
-
Освоение Ajax: Часть 1: Введение в Ajax (Брэт Маклафлин, developerWorks, апрель 2006): Дополнительная информация по Ajax.
-
Кэширование с JSON
(Бакуль Патель, developerWorks, июнь 2007): Узнайте, как кэшировать метаданные на стороне клиента при помощи серверного кода, предоставляющего строковые метаданные в JSON-формате.
-
Ajax и REST, часть 1 (Билл Хиггинс, developerWorks, октябрь 2006): Узнайте о преимуществах архитектурного стиля Ajax/REST для функциональных Web-приложений.
-
Придайте динамизма при помощи PHP (Джек Херрингтон (Jack Herrington), developerWorks, февраль 2006): Узнайте, как использовать динамические возможности PHP V5.
-
PHP-разработка Ajax-способом, часть 1: Начало работы (Шон Кэлли (Sean Kelly), developerWorks, май 2006): Начало работы с PHP и Ajax.
-
Центр ресурсов по Ajax на IBM developerWorks: Дополнительные статьи и руководства по Ajax.
-
Раздел IBM developerWorks XML: Все необходимое для изучения XML.
-
Раздел IBM developerWorks SOA и Web-сервисов: Дополнительная информация по SOA и Web-сервисам.
-
Web-сайт JSON: Все о JavaScript Object Notation (JSON).
-
Сообщество сторонников открытого исходного кода PHP: Все о PHP.
-
Руководство по PHP: Чрезвычайно полезный ресурс по PHP, предлагаемый на 23 языках.
-
Сертификация IBM XML: Узнайте, как получить сертификат IBM-Certified Developer по XML и смежным технологиям.
-
Техническая библиотека по XML: Большое разнообразие технических статей и советов, руководств, стандартов и IBM Redbooks на developerWorks XML Zone.
-
Технические события и web-трансляции на developerWorks: Следите за технологией.
Получить продукты и технологии
-
Web-сайт PHP Extension and Application Repository (PEAR): Загрузите библиотеку
Services_JSON. -
Пробное программное обеспечение IBM: Разработайте ваш следующий проект, используя пробное программное обеспечение, доступное для загрузки непосредственно с developerWorks.
Обсудить
- Примите участие в обсуждении материала на форуме.
-
Дискуссионные форумы XML-раздела: Принимайте участие в любых форумах, посвященных XML.
-
Блоги developerWorks: Подключайтесь к сообществу developerWorks.
Эдвард Принг (Edward Pring) имеет ученую степень магистра естественных наук в области информационных технологий от Нью-Йоркского Университета и степерь бакалавра наук в области математических наук от университета в Стенфорде. В составе коллектива IBM Research он участвовал в работе над широким диапазоном продуктов и технологий IBM, включая операционные системы, издательские приложения, эмуляторы терминалов для мейнфреймов, продукты антивирусной защиты для персональных компьютеров, автоматизацию сетевых функций для Digital Immune System, а также продукты для визуализации и анализа производительности для web-сервисов. Эдвард имеет патенты во всех этих областях.
Джон Морар (John Morar) - доктор философии, имеющий огромный опыт работы в области полупроводников и исследовании компьютерных вирусов. Написал 70 статей в научных журналах, а также имеет патенты в области производства устройств, обнаружения компьютерных вирусов, Web-сервисов и экономических систем. В настоящее время доктор Морар руководит исследовательской группой, занимающейся вопросами использования Web-сервисов внутри и между предприятиями.
Сентил Натан (Senthil Nathan) работает старшим инженером-программистом в IBM T.J. Watson Research Center в Hawthorne, New York. Имеет 21-летний опыт создания программного обеспечения для корпоративных приложений различных типов. В настоящее время в сферу его профессиональных интересов входят технологии SOA, Web-сервисы, Java 2 Platform, Enterprise Edition (J2EE), PHP, Web 2.0 и Ajax.