1. Внутренние сущности
- напоминают строковые переменные, связывающие имя с фрагментом текста.
Пример:
<!ENTITY Copyright "Copyright 2000 YourCompanyName. All Rights Reserved.">
В процессе обработки документа все экземпляры &Соруright заменяются текстом «Copyright 2000 YourCompanyName. All Rights Reserved».
Весь код XML в заменяющем тексте обрабатывается так, словно он присутствовал в исходном документе.
2. Внешние сущности
- используются для ссылок на содержание, находящееся в другом файле. Сущности этого типа могут содержать текстовую информацию, но также могут ссылаться и на двоичные данные (например, графику).
Пример:
<!ENTITY Copyright SYSTEM "http://yoursite.com/administer/copyright.xml">
При последующей обработке документа XML все ссылки &Соруright заменяются содержимым документа copyright.xml. Весь код XML в заменяющем тексте обрабатывается так, словно он присутствовал в исходном документе.
Внешние сущности также удобно использовать для ссылок на графические изображения. Например, если вы хотите включить в документ XML графический логотип, создайте внешнюю сущность:
<!ENTITY food_picture SYSTEM http://yoursite.com/food/logo.gif>
Как и в предыдущем примере, все ссылки &food_picture заменяются графическим изображением, на которое указывает ссылка. Поскольку данные являются двоичными, а не текстовыми, они не интерпретируются.
РНР и ХМL
Для работы с XML в РНР используется пакет Джеймса Кларка (James Clark) Expat (XML Parser Toolkit). Expat включается в поставку Apache.
Чтобы воспользоваться функциональными возможностями XML в РНР, необходимо настроить РНР с ключом -with-xml.
Компоненты документа XML:
открывающие теги;
атрибуты;
символьные данные;
закрывающие теги;
инструкции по обработке;
синтаксические объявления;
внешние ссылки на сущности;
необработанные сущности;
прочие компоненты (комментарии, объявления XML и т. д.).
Для эффективной обработки документов XML необходимо определить пользовательские функции-обработчики (handlers), обрабатывающие каждый из перечисленных компонентов.
Определенные функции подключаются к процессу обработки XML стандартными средствами РНР.
Общий процесс обработки кода XML в РНР:
Определить пользовательские функции. Для постоянной работы с документами XML, эти функции достаточно написать всего один раз и в дальнейшем вносить в них необходимые изменения.
Создать анализатор (parser) кода XML, который будет использоваться для обработки документа. Анализатор создается вызовом функции xml_parser_create( ).
При помощи стандартных функций зарегистрировать созданные функции в анализаторе XML.
Открыть файл XML, прочитать содержащиеся в нем данные и передать их анализатору XML. Обработка данных выполняется простым вызовом xml_parse( ). В процессе своей работы эта функция обеспечивает косвенный вызов всех определенных вами обработчиков.
Уничтожить анализатор XML, чтобы освободить задействованные им ресурсы.
Подключение пользовательских функций к обработке XML
Функция xml_set_character_data_handler()
- регистрирует пользовательскую функцию для работы с символьными данными. Синтаксис:
xml_set_character_data_handler(анализатор, обработчик_символьных_данных)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой при обработке символьных данных. Определение функции-обработчика должно выглядеть так:
function обработчик_символьных_данных (анализатор, данные) {
...
}
Первый параметр определяет анализатор XML, а второй — символьные данные, подлежащие обработке.
Функция xml_set_default_handler( )
- регистрирует пользовательскую функцию для всех незарегистрированных компонентов документа XML. В частности, к числу таких компонентов относятся пролог XML и комментарии. Синтаксис:
xml_set_default_handler(анализатор, обработчик_по_умолчанию)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой по умолчанию. Определение функции-обработчика должно выглядеть так:
function обработчик_по_умолчанию (анализатор, данные) {
...
}
Первый параметр определяет анализатор XML, а второй — символьные данные, подлежащие обработке.
Функция xml_set_element_handler( )
- регистрирует пользовательские функции для обработки открывающих и закрывающих тегов элементов. Синтаксис:
xml_set_element_handler(анализатор, обработчик_открывающих_тегов, обработчик_закрывающих_тегов)
Первый параметр определяет анализатор XML. Второй и третий параметры определяют имена функций, используемых для обработки, соответственно, открывающих и закрывающих тегов.
Определение обработчика открывающих тегов должно выглядеть так:
function обработчик_открывающих_тегов (анализатор, имя_тега, атрибуты[ ]) {...}
Обработчик закрывающих тегов определяется следующим образом:
function обработчик_закрывающих_тегов (анализатор, имя_тега) {...}
Первый параметр определяет анализатор XML, второй — имя закрывающего тега для анализируемого элемента.
Функция xml_set_external_entity_ref_handler( )
- регистрирует пользовательскую функцию для обработки внешних ссылок на сущности. Синтаксис:
xml_set_external_entity_ref_handler(анализатор, обработчик_внешних_ссылок)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой при обработке внешних ссылок. Определение функции-обработчика должно выглядеть так:
function обработчик_внешних_ссылок (анализатор, ссылка, база, системный_идентификатор, открытый_идентификатор) {
...}
Первый параметр определяет анализатор XML. Второй параметр определяет имя ссылки, четвертый — системный идентификатор ссылки на сущность, а пятый — открытый идентификатор ссылки. Третий параметр, база, в настоящее время не используется, однако его объявление все равно обязательно.
Функция xml_set_notation_decl_handler ( )
- регистрирует пользовательскую функцию для обработки синтаксических объявлений. Синтаксис:
xml_set_notation_decl_handler(анализатор, обработчик_синтаксических_обьявлений)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой при обработке синтаксических объявлений.
Определение функции-обработчика должно выглядеть так:
function обработчик_синтаксических_обьявлений (анализатор, ссылка, база, системный_идентификатор, открытый_идентификатор) {
...}
Первый параметр определяет анализатор XML. Второй параметр определяет имя объявления, четвертый — системный идентификатор, а пятый — открытый идентификатор объявления. Третий параметр, база, в настоящее время не используется, однако его объявление все равно обязательно.
Функция xml_set_object( )
- ассоциирует анализатор XML с некоторым объектом. Синтаксис:
xml_set_object(анализатор, object &о6ъект)
Первый параметр определяет анализатор XML, а второй содержит ссылку на объект, методы которого будут использоваться для обработки компонентов XML. Таким образом, функция xml_set_object связывает анализатор с объектом. Как правило, она вызывается в конструкторе объекта перед определениями функций-обработчиков:
class xmlDB {
VAR $xmlparser:
function xmlDB( ) {
$this->xmlparser = xml_parser_create();
// Связать анализатор с объектом
xml_set_object($this->xmlparser &$this);
// Определить функции-обработчики
xml_set_element_handler($this->xmlparser, "startTag","endTag");
xml_set_character_data($this->xmlparser,"characterData");
}
... Определения функций-обработчиков startTag, endTag, characterData и т.д. ...
} // class xmlDB
Функция xml_set_processing_instruction_handler( )
- регистрирует пользовательскую функцию для работы с Pi-инструкциями.
Синтаксис:
xml_set_processing_instruction_handler(анализатор, обработчик_инструкций)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой при обработке Pi-инструкций. Определение функции-обработчика должно выглядеть так:
function обработчик_инструкций (анализатор, приложение, инструкция) {
...}
Первый параметр определяет анализатор XML, второй — имя приложения, выполняющего инструкции, а третий — инструкцию, передаваемую приложению.
Функция xml_set_unparsed_entity_decl_handler( )
- регистрирует пользовательскую функцию для необработанных внешних ссылок на сущности. Синтаксис:
xml_set_external_entity_ref_handler(анализатор, обработчик_внешних_ссылок)
Первый параметр определяет анализатор XML, а второй — имя пользовательской функции, используемой для обработки необработанных внешних ссылок.
Определение функции-обработчика должно выглядеть так:
function обработчик_внешних_ссылок (анализатор, сущность, база, системный_идентификатор, открытый_идентификатор, имя_объявления) {
...
}
Первый параметр — анализатор XML,
второй параметр — ссылки,
третий параметр (база) в настоящее время не используется, однако его объявление все равно обязательно,
четвертый — системный идентификатор ссылки на сущность,
пятый — открытый идентификатор ссылки.
шестой параметр — имя синтаксического объявления.
Функции обработки кода XML
Функция xml_parser_create( )
Перед обработкой документа XML необходимо предварительно создать анализатор. Синтаксис:
xml_parser_create([кодировка])
Необязательный параметр определяет кодировку исходного текста. В настоящее время поддерживаются три варианта кодировки:
UTF-8;
US-ASCII;
ISO-8859-1 (используется по умолчанию).
По аналогии с тем, как функция fopen( ) возвращает манипулятор открытого файла, функция xml_parser_create( ) возвращает манипулятор, используемый для вызова различных функций в процессе обработки XML. При одновременной обработке нескольких документов можно создать сразу несколько анализаторов.
Функция xml_parse( )
- выполняет обработку документа XML.
Синтаксис:
xml_parse(анализатор, данные [завершение])
Первый параметр определяет анализатор XML (используется значение, возвращаемое при вызове xml_parser_create( )).
Если необязательный параметр завершение равен TRUE, передаваемый фрагмент данных является последним. Как правило, это происходит при достижении конца обрабатываемого файла.
Функция xml_parser_free( )
- освобождает ресурсы, выделенные для работы анализатора. Синтаксис:
xml_parser_free(анализатор)
Параметр функции определяет анализатор XML.
Другие полезные функции
Функция xml_get_error_code( )
- получает код ошибки, возникшей в процессе обработки XML. Код ошибки передается функции xml_error_string( ) для интерпретации.
Синтаксис:
xml_error_code(анализатор)
Параметр функции определяет анализатор XML.
Функция xml_error_string( )
- возвращает текстовое описание ошибки по ее коду.
Ошибкам, возникающим в процессе анализа кода XML, присваиваются числовые коды.
Синтаксис:
xml_error_string(код)
В параметре функции передается код ошибки (полученный при вызове функции xml_get_error_code( )).
Функция xml_get_current_line_number( )
- возвращает номер текущей строки, обрабатываемой анализатором XML. Синтаксис:
xml_get_current_line_number(анализатор)
Параметр функции определяет анализатор XML.
Пример:
while ($line = fread($fh, 4096)) :
if (! xml_parse($xml_parser, $line, feof($fh)));
$err_string = xml_error_string(xml_get_error_code($xml_parser));
$line_number = xml_get_current_line_number($xml_parser);
print "Error! [Line $line_number]: $err_string";
endif;
endwhile;
Например, если ошибка была обнаружена в шестой строке файла, определяемого манипулятором $fh, сообщение будет выглядеть примерно так:
Error! [Line 6]:mismatched tag
Функция xml_get_current_colunin_number( )
может использоваться в сочетании с xml_get_current_line_number( ) для определения точного местонахождения ошибки в документе XML. Синтаксис:
xml_get_current_column_number(анализатор)
Параметр функции определяет анализатор XML.
Пример:
while ($line = fread($fh. 4096)) :
if (! xml_parse($xml_parser, $line, feof($fh))):
$err_string = xml_error_string(xml_get_error_code($xml_parser));
$line_number = xml_get_current_line_number($xml_parser);
$column_number = xml_get_current_column_number($xml_parser)
print "Error! [Line $line_nuimber, Column $column_number]: $err_string";
endif;
endwhile;
Например, если ошибка была обнаружена в шестой строке файла, определяемого манипулятором $fh, сообщение будет выглядеть примерно так:
Error! [Line 6 Column 2]:mismatched tag
Параметры анализатора XML
В настоящее время в РНР поддерживаются два параметра, влияющих на работу анализатора XML:
XML_OPTION_CASE_FOLDING — автоматическое преобразование имен тегов к верхнему регистру;
XML_OPTION_TARGET_ENCODING — кодировка документа на выходе анализатора XML. В настоящее время поддерживаются кодировки UTF-8, ISO-8859-1 и US-ASCII.
Для получения текущих значений и модификации этих параметров применяются, соответственно, функции xml_parser_get_option( ) и xml_parser_set_option( ).
Функция xml_parser_get_option( )
- получает текущее значение параметра анализатора XML.
Синтаксис:
xml_parser_get_option(анализатор, параметр)
Первый параметр функции определяет анализатор XML, а второй — имя интересующего параметра.
Пример:
$setting = xml_parser_get_option($xml_parser, XML_OPTION_CASE_FOLDING);
print "Case Folding: $setting";
Если параметру XML_OPTION_CASE_FOLDING не присваивалось другое значение, функция вернет значение по умолчанию. В этом случае будет выведен следующий результат:
Case Folding: 1
Функция xml_parser_set_option()
- задает значение параметра анализатора XML.
Синтаксис:
xml_parser_set_option(анализатор, параметр, значение)
Первый параметр функции определяет анализатор XML, второй — имя интересующего параметра, а третий — его новое значение.
Пример:
$setting = xml_parser_set_option($xml_parser, XML_OPTION_TARGER_ENCODING."UTF-8"):
В результате выполнения этой команды выходная кодировка документа изменяется с ISO-8859-1 на UTF-8.
Преобразование XML в HTML
Предположим, имеется документ XML bookmarks.xml, содержащий список ссылок. Он выглядит примерно так:
<?xml version="1.0"?>
<website>
<title>Epicurious</title>
<url>http://www.epicurious.com</url>
<description>
Epicurious is a great online cooking resource, providing tutorials.
recipes, forums and more.
</description> </website>
Задача: преобразовать bookmarks.xml и вывести его содержимое в формате, совместимом с форматом браузера.
Преобразование XML в HTML
Class XMLHTML {
VAR $xmlparser: VAR $tagcolor ="#800000";
VAR $datacolor ="#0000ff";
function XMLHTML( ) {
$this->xmlparser = xml_parser_create();
xml_set_object($this->xmlparser. &$this);
xml_set_element_handler($this->xmlparser, "startTag", "endTag");
xml_set_character_data_handler($this->xmlparser. "characterData");
}
// Функция отвечает за обработку всех открывающих тегов.
function startTag($parser, $tagname, $attributes) {
GLOBAL $tagcolor;
print "<font size=\"-2\" color=\"$this->tagcolor\" face=\"arial,
verdana\ ">&1 t ; $tagname> ; </f ont> <br>" ;
// Функция отвечает за обработку всех символьных данных.
function characterData($parser. $characterData) {
GLOBAL $datacolor;
print "<font size=\"-2\" color=\"$this->datacolor\" face=\"arial,
verdana\ "> $characterData</font> <br>";
// Функция отвечает за обработку всех закрывающих тегов.
function endTag(Sparser, $tagname) {
GLOBAL Stagcolor;
print "<font size=\"-2\" color=\"$this->tagcolor\" face=\"arial, verdana\"></
$tagname></font> <br>";
}
function.parse($fp) {
// xml_parse($this->xm1parser,$data);
// Обработать файл XML
while ( $line = fread($fp. 4096) ) :
// При возникновении ошибки прервать обработку // и вывести сообщение об ошибке.
if ( ! xml_parse($this->xmlparser, $line, feof($fp))) :
die(sprintf("XML error: %s at line %d",
xml_error_sthng(xml_get_error_code($this->xmlparser)),
xml_get_curren_line_number($this->xml parser)));
endif;
endwhile;
}}
// Открыть файл XML для обработки
$xml_file = "bookmarks. xml";
$fp = f open ($xml_flie, "r");
// Создать новый объект
$xml_parser = new XMLHTML;
// Обработать $xml_file
$xml_parser->parse($fp);
?>
В результате преобразования файл bookmarks.xml выводится в браузере в следующем виде:
<WEBSITE>
<TITLE>
Epicurious
</TITLE>
<URL>
http://www.epicurious.com
</URL>
<DESCRIPTION>
Epicurious is a great online cooking resource, providing tutorials, recipes, forums and more.
</DESCRIPTION>
</WEBSITE>
Далее CSS!
Таблицы стилей XSL
- описывают, как должны преобразовываться документы XML в другие форматы, такие, как HTML или RTF. Но таблицы стилей XML - это больше, чем преобразователи форматов; они также предоставляют механизм для манипулирования данными. Например, данные можно сортировать, проводить по ним поиск, удалять или добавлять прямо из окна браузера.
Пример таблицы стилей для языка XML:
<?xml version = "1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/TR/WD-xsl">
<!-декларация, что документ является таблицей стилей и что он связан с xsl: namespace->
<xsl:template match="/">
<!-Применить шаблон ко всему в исходном документе XML ->
<HTML>
<BODY>
<H1>Editor Contacts</H1>
<xsl:for-each select="editor_contacts/editor">
<H2>Name: <xsl:value-of select="first_name">
<xsl:value-of select="last_name"/></H2>
<P>Title: <xsl:value-of select="title"/></P>
<P>Publication: <xsl:value-of select="publication"/></P>
<P>Street Address: <xsl:value-of select="address/street"/></P>
<P>City: <xsl:value-of select="address/city"/></P>
<P>State: <xsl:value-of select="address/state"/></P>
<P>Zip: <xsl:value-of select="address/zip"/></P>
<P>E-Mail: <xsl:value-of select="e_mail"/></P>
</xsl:for-each>
</BODY>
</HTML>
</xsl:template>
</xsl:stylesheet>
При сохранении файла на жестком диске под именем EDITORS.XSL (или любым другим) этот шаблон будет применен к EDITORS.XML при добавлении в него следующей строки после первой:
<?xml-stylesheet type="text/xsl" href="editors.xsl" ?>