Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекция10_xml.doc
Скачиваний:
2
Добавлен:
08.08.2019
Размер:
151.55 Кб
Скачать

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:

  1. открывающие теги;

  2. атрибуты;

  3. символьные данные;

  4. закрывающие теги;

  5. инструкции по обработке;

  6. синтаксические объявления;

  7. внешние ссылки на сущности;

  8. необработанные сущности;

  9. прочие компоненты (комментарии, объявления XML и т. д.).

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

Определенные функции подключаются к процессу обработки XML стандартными средствами РНР.

Общий процесс обработки кода XML в РНР:

  1. Определить пользовательские функции. Для постоянной работы с документами XML, эти функции достаточно написать всего один раз и в дальнейшем вносить в них необходимые изменения.

  2. Создать анализатор (parser) кода XML, который будет использоваться для обработки документа. Анализатор создается вызовом функции xml_parser_create( ).

  3. При помощи стандартных функций зарегистрировать созданные функции в анализаторе XML.

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

  5. Уничтожить анализатор 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&gt ; </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" ?>