Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Котеров Д. В., Костарев А. Ф. - PHP 5. 2-е издание (В подлиннике) - 2008

.pdf
Скачиваний:
6114
Добавлен:
29.02.2016
Размер:
11.36 Mб
Скачать

744

Часть VI. XML в PHP 5

 

 

 

 

 

 

Рис. 37.21. Отображение свойств класса domProcessingInstruction

Функция showPIProperties() отображения свойств узла domAttr представлена в листинге 37.32.

Листинг 37.32. Файл shownodeinfo/showpiprop.inc

<?php ## Отображение свойств класса domProceccingInstruction. /**

*Отобразить свойства узла класса domProceccingInstruction

*в формате HTML

*@param domProceccingInstruction $domproceccingInstruction

*@return void — HTML-код помещается в буфер вывода

*/

function showPIProperties($domprocessinginstruction) {?>

><TR

><TD>target (Приложение):</TD

><TD><?php echo utf8decode($domprocessinginstruction->target)?></TD ></TR

><TR

><TD>data(Код):</TD

Глава 37. DOM1 — объектная модель XML-документа

745

><TD><?php echo utf8decode($domprocessinginstruction->data)?></TD

></TR

<?php

}

Пример отображения свойств класса domProcessingInstruction показан на рис. 37.21.

Свойства класса domCharacterData

Класс domCharacterData является виртуальным. Он не имеет текстового представления в XML-документе. В качестве его подклассов выступают классы domText с подклассом domCDATASection и класс domComment (рис. 37.22).

domNode

domCharacterData

domText domComment

domCDATASection

Рис. 37.22. Иерархия суперклассов класса domCharacterData

Класс domCharacterData поддерживает общие для классов domComment, domCDATASection

и domText свойства и методы.

Рассмотрим свойства класса domCharacterData:

string data — текстовое содержание узла;

int length — длина текста.

Заметим, что свойство data экземпляра класса domCharacterData, в отличие от большинства свойств, доступно для записи. Вы можете изменить содержание узлов domText, domCDATASection, domComment, просто присвоив новое значение свойству data.

Программа отображения этих свойств приведена в листинге 37.33.

Листинг 37.33. Файл shownodeinfo/showcharacterdataprop.inc

<?php ## Отображение свойств класса domCharacterData.

/**

*Отобразить свойства узла класса domCharacterData в формате HTML

*@param domCharacterData $domelement — узел класса

*domText, domCDATASection или domComment

*@return void — HTML-код помещается в буфер вывода

*/

function showCharacterDataProperties($domcharacterdata) {

?>

746

Часть VI. XML в PHP 5

><TR

><TD>data (Данные):</TD

><TD><?php echo utf8decode($domcharacterdata->data)?></TD

></TR

><TR

><TD>length (Длина):</TD

><TD><?php echo $domcharacterdata->length?></TD

></TR

<?php

}

Методы данного класса (substringData(), appendData(), insertData(), replaceData()) мы рассмотрим в разд. "Методы класса domCharacterData для работы с текстом" да-

лее в этой главе.

Свойства класса domText

Класс domText является подклассом класса domCharacterData (рис. 37.23).

domNode

domCharacterData

domText

Рис. 37.23. Иерархия суперклассов класса domText

Дочерние узлы узла класса domText отсутствуют.

Кроме свойств data и length суперкласса domCharacterData узел класса domText имеет еще одно дополнительное свойство: wholeText — текст узла. Программа отображения свойства приведена в листинге 37.34.

Листинг 37.34. Файл shownodeinfo/showtextprop.inc

<?php ## Отображение свойств класса domText. /**

*Отобразить свойства узла класса domText в формате HTML

*@param domText $domtext — текстовый узел XML-документа

* @return void — HTML-код помещается в буфер вывода

*/

function showTextProperties($domtext) { ?>

><TR

><TD>wholeText (Весь текст):</TD

><TD><?php echo utf8decode($domtext->wholeText)?></TD ></TR

<?php

}

Глава 37. DOM1 — объектная модель XML-документа

747

Пример отображения свойств класса domText показан на рис. 37.24.

Рис. 37.24. Отображение свойств класса domText

Свойства класса domCDATASection

Класс domCDATASection является подклассом класса domText (рис. 37.25).

Дочерние узлы у узла класса domCDATASection отсутствуют.

Дополнительных свойств по отношению к суперклассу domText рассматриваемый класс не имеет.

domNode

domCharacterData

domCDATASection

Рис. 37.25. Иерархия суперклассов класса domCDATASection

748 Часть VI. XML в PHP 5

Пример отображения свойств узла класса domCDATASection показан на рис. 37.26.

Рис. 37.26. Отображение свойств класса domCDATASection

Свойства класса domComment

Класс domComment является подклассом класса domCharacterData (рис. 37.27).

Дочерние узлы у узла класса domComment отсутствуют.

domNode

domCharacterData

domComment

Рис. 37.27. Иерархия суперклассов класса domComment

Глава 37. DOM1 — объектная модель XML-документа

749

Дополнительных свойств по отношению к суперклассу domCharacterData данный класс не имеет.

Пример отображения свойств класса domComment показан на рис. 37.28.

Рис. 37.28. Отображение свойств класса domComment

Работу приведенных в данном разделе сценариев вы можете посмотреть на сайте по адресу http://php5xml.nevod.ru/scripts/dom1/shownodeinfo/. Кроме этого, вы можете получить копию сценариев по адресам:

http://php5xml.nevod.ru/chapter/dom/zipkoi8.php (кодировка KOI8-R);

http://php5xml.nevod.ru/chapter/dom/zip1251.php (кодировка Windows-1251).

Установите их на своем WWW-сервере и используйте для анализа структуры XMLдокументов.

Построение и корректировка XML-документа

До настоящего момента мы рассмотрели свойства узлов XML-документа и два метода создания XML-документа "целиком". В первом случае мы вставляли XML-узлы в тело PHP-программы (см. листинг 37.7), во втором случае (см. листинг 37.6) мы

750

Часть VI. XML в PHP 5

загружали документ в DOM-дерево методом loadXML() (load()) класса domDocument и на основе загруженного дерева формировали выходной XML-документ.

Используя функции работы с выходным буфером (ob_start(), ob_get_contents(), ob_end_clean()), можно получить комбинированный вариант этих двух методов (листинг 37.35).

Листинг 37.35. Файл kombi/kombi.php

<?php ## Комбинированный вариант формирования DOM-дерева require_once 'unicode.inc';

/**

*Создать объект класса domDocument на основе XML-документа,

*сформированного скриптом script1.php

*@return — экземпляр класса domDocument

*/

function loadprogram() {

$domdocument = new domDocument('1.0', Encoding);

ob_start();

 

// включить буферизацию вывода

include_once 'script1.php';

// заполнение буфера XML-документом

// построить DOM-дерево на основе содержимого буфера

$domdocument->loadXML(ob_get_contents());

ob_end_clean();

// очистить буфер и выключить буферизацию

return $domdocument;

 

 

}

 

 

$domdocument = loadprogram();

// сформировать XML-документ

echo $domdocument->saveXML();

// отобразить его

Рассмотрим теперь вопросы, связанные с методами построения и корректировки дерева узлов (объектов).

Создание экземпляра класса стандарта DOM

PHP 5 предоставляет два варианта создания экземпляра узла класса DOM:

вызов метода create<имя_класса> класса domDocument;

формирование экземпляра конструктором new.

Оба варианта показаны в листинге 37.36.

Листинг 37.36. Файл methods/newandcreate.php

<?php ## Два способа создания экземпляра класса DOM. require_once 'unicode.inc';

$domdocument = new domDocument('1.0', Encoding); // документ $element1 = $domdocument->createElement('body');

$element2 = new domElement('body');

При создании экземпляра методом класса domDocument новый экземпляр принадлежит документу, вызвавшему данный метод (переменная ownerDocument указывает на

Глава 37. DOM1 — объектная модель XML-документа

751

экземпляр класса domDocument). Таким образом, он не может без дополнительных операций быть перенесен в другой XML-документ.

При создании же экземпляра конструктором new новый экземпляр не связан ни с каким-либо документом и может быть позже включен в требуемый документ.

В табл. 37.4 приведен список методов класса domDocument, предназначенных для создания различных типов узлов.

Таблица 37.4. Список методов создания узлов DOM и их конструкторы

 

Экземпляр класса,

 

Метод класса domDocument

созданный

Параметры

 

конструктором new

 

 

 

 

createElement()

DomElement()

string tagName — èìÿ

 

 

òåãà

createDocumentFragment()

DomDocumentFragment()

createTextNode()

DomText()

string data — текст

createComment()

DomComment()

string data — текст

 

 

комментария

createCDATASection()

DomCDATASection()

string data — текст

 

 

секции

createProcessingInstruction()

DomProcessingInstruction()

string target — èìÿ

 

 

приложения;

 

 

string data — текст

 

 

команд приложения

createAttribute()

domAttr()

string name — èìÿ

 

 

атрибута

createEntityReference()

DomEntityReference()

string name — èìÿ

 

 

компонента

 

 

 

Обратите внимание, что между именами классов и методами создания класса domDocument существует взаимооднозначное соответствие create<имя_узла> dom<имя_узла>. Исключение составляют методы сreateTextNode() и createAttrbute(), которые создают объекты классов domText и domAttr соответственно.

Перечень методов класса domDocument закреплен в стандарте DOM. Так как данные методы в PHP 5 являются функциями, то возможно использование в названии методов строчных и прописных букв. Например, имена createElement(), createelement(), CREATEELEMENT() указывают на одну и ту же функцию. Но мы в дальнейшем будем придерживаться стандартного способа написания имени метода, т. к. в реализациях DOM для других языков данные вольности недопустимы.

То же самое справедливо и для имен классов — имена классов domText, domtext и DOMTEXT указывают на один и тот же класс. Мы же будем придерживаться стандартной формы написания имени: domText.

В качестве примера использования описанных выше функций приведем текст программы, формирующей XHTML-код таблицы (листинг 37.37).

752 Часть VI. XML в PHP 5

Листинг 37.37. Файл methods/createmeths.php

<?php ## Пример использования методов класса domDocument

## и конструкторов класса.

 

require_once 'unicode.inc';

 

$listNodes = Array(

 

 

"Element"

=> Array("string tagName"=>"имя тега"),

"DocumentFragment"

=> Array(),

 

"TextNode"

=> Array("string data"=>"текст"),

"Comment"

=> Array("string data"=>"текст комментария"),

"CDATASection"

=> Array("string data"=>"текст секции"),

"ProcessingInstruction"=> Array("string target"=>"имя приложения",

 

"string data"=>"текст команд приложения"),

"Attribute"

=> Array("string name"=>"имя атрибута"),

"EntityReference"

=> Array("string name"=>"имя компонента")

);

 

 

$domdocument = new domDocument('1.0', Encoding); // документ

$tablenode = $domdocument->createElement('table'); // корневой элемент

$domdocument->appendChild($tablenode);

// добавить к документу

$comment = utf8encode('Заголовок таблицы');

// комментарий

$tablenode->appendChild($domdocument->createComment($comment));

$trnode = $domdocument->createElement('tr');

 

$tablenode->appendChild($trnode);

// строка заголовка

$heads = Array('Метод класса domDocument', 'Конструктор new', 'Параметры'); foreach ($heads as $head) { // сформировать теги TH заголовка

$thnode = $domdocument->createElement('th'); $trnode->appendChild($thnode);

$textnode = $domdocument->createTextNode(utf8encode($head)); $thnode->appendChild($textnode);

}

$comment = utf8encode('Тело таблицы'); $tablenode->appendChild($domdocument->createComment($comment)); foreach ($listNodes as $node => $pars) { // по всем типам узлов

$comment = utf8encode("Узел $node"); $tablenode->appendChild($domdocument->createComment($comment));

//строка описания метода, класса, параметров $trnode = new domElement('tr'); $tablenode->appendChild($trnode);

$method = "create$node()";

//имя класса для методов createTextNode и

//createAttribute формируется нестандартно $new = ($node == 'TextNode'? 'domText()' :

($node == 'Attribute'? 'domAttr' : "dom$node()"));

foreach (Array($method,$new) as $funcname) { // столбцы метода и класса $tdnode = new domElement('td');

$trnode->appendChild($tdnode);

Глава 37. DOM1 — объектная модель XML-документа

753

$text = new domText(utf8encode($funcname));

 

$tdnode->appendChild($text);

// добавить имя функции

 

}

 

 

 

$tdnode = new domElement('td');

// столбец описания параметров

 

$trnode->appendChild($tdnode);

 

 

$i = 0; $n = count($pars); $content = '';

 

foreach ($pars as $par => $descr) {

// по всем параметрам

 

// сформировать текстовые узлы: "параметр" " — " "описание"

 

$tdnode->appendChild(new domText(utf8encode($par)));

 

$tdnode->appendChild(new domText(" — "));

 

$tdnode->appendChild(new domText(utf8encode($descr)));

 

if (++$i < $n)

// если не последний параметр, добавить тег BR

 

$tdnode->appendChild(new domElement('br'));

 

}

 

 

 

}

 

 

 

$domdocument->formatOutput=true;

 

 

$tablexml = utf8decode($domdocument->saveXML($tablenode));

 

echo $tablexml;

// вывести XHTML-текст таблицы

 

Обратите внимание, что создание экземпляра класса не означает автоматическое добавление его в дерево документа. Для размещения узла в дереве используется метод $node->appendChild($child) класса domNode. Он добавляет к узлу $node дочерний элемент $child. Полный список методов класса domNode мы приведем в разд. "Кор-

ректировка дерева узлов" далее в этой главе.

Таблица и ее заголовок в приведенном выше примере создаются методами класса domDocument, тело таблицы — конструктором new класса domElement. Сформированный XHTML код таблицы представлен в листинге 37.38.

Листинг 37.38. XHTML-код таблицы, сформированный методами класса domDocument и конструкторами класса

<table>

<!--Заголовок таблицы--> <tr>

<th>Метод класса domDocument</th> <th>Конструктор new</th> <th>Параметры</th>

</tr>

<!--Тело таблицы--> <!--Узел Element-->

<tr>

<td>createElement()</td>

<td>domElement()</td>

<td>string tagName — имя тега</td> </tr>

<!--Узел DocumentFragment--> <tr>

<td>createDocumentFragment()</td>

<td>domDocumentFragment()</td>

Тут вы можете оставить комментарий к выбранному абзацу или сообщить об ошибке.

Оставленные комментарии видны всем.