K4:Обработка XML документов
From In-Portal Developers Guide
Line 111: | Line 111: | ||
{{TipBox|The below description of the contents of an object of the kXMLNode class will be based on the example at the beginning of the article.}} | {{TipBox|The below description of the contents of an object of the kXMLNode class will be based on the example at the beginning of the article.}} | ||
- | |||
- | + | The parent (root) object will be assigned to the <code>$root_node</code> variable, i.e. the xml-element object "<code>our_document</code>". The "<code>Children</code>" (private) attribute contains an array of all child elements of the current element. In this example, these are the two elements "<code>some_tag</code>" and "<code>planet_earth</code>". The last one has two "<code>continent</code>" child elements. It's import to understand that array elements are the same as other objects, they can themselves have child elements, etc. | |
- | + | Each element has a <code>Position</code> attribute. This is its order in the elements (same level elements, for example - "country" Canada and "country" USA). The "<code>firstChild</code>" and "<code>lastChild</code>" elements contain the first and last (from the point of view of their <code>Position</code>) child elements, respectively. | |
+ | |||
+ | For further processing of received information the <code>kXMLNode</code> class methods and attributes are used. | ||
== Практическое использование kXMLHelper == | == Практическое использование kXMLHelper == |
Revision as of 18:26, 18 April 2009
| ||
---|---|---|
Статьи в этой категории | ||
|
XML
is a convenient tree-structure format of organizing data. Each element can contain a value and/or other elements. Text inside an element can alternate with child elements, but it will still be considered a single value. Moreover, each element can have attributes. All of this is shown in the below example (let it be a file called "sample.xml
"):
<?xml version="1.0" encoding="utf-8"?> <our_document> <some_tag> Some tag's content. </some_tag> <planet_earth> <continent id="1"> North America <country id="1"> Canada </country> <country id="2"> USA </country> </continent> <continent id="2"> Europe <country id="1"> Estonia </country> <country id="2"> Latvia </country> <country id="3"> Lithuania </country> </continent> </planet_earth> </our_document>
Contents |
The CDATA Block
If the content of an element needs to contain symbols that could disrupt the correct parsing of an XML document, then the contents need to be inside a CDATA block. Some of these symbols include ">
", "<
" и "&
". The syntax of a CDATA
block looks like this:
<![CDATA[Some symbolic data, that > breaks & xml]]>
Data inside a CDATA block should not contain "]]>
" because it will considered the end of the block. If it's absolutely necessary to have "]]>
" then the following approach will work:
<![CDATA[]]]]><![CDATA[>]]>
In the above example, the contents are separated into two parts, each of which is inside a CDATA
block. It's especially convenient to use CDATA
in the situation where XML
needs to be written to show to a user, but won't be processed when parsing the XML document.
Getting an XML Document
Before parsing an XML
document, it has to be received.
Getting a Local File
To get a local file (i.e. located on the same computer as the site), the standard file_get_contents function can be used. This function returns the contents of file, the path of which is passed as its first argument.
$file_contents = file_get_contents(WRITEABLE . '/user_files/sample.xml');
Getting a Remote File
The file_get_contents function also allows retrieving the contents of a remote file. However, for security reasons, the server may restrict this functionality. Therefore, it's strongly recommended to use the standard K4 kCurlHelper
class to retrieve remote files.
$curl_helper =& $this->Application->recallObject('CurlHelper'); /* @var $curl_helper kCurlHelper */ $xml_data = $curl_helper->Send('http://sample-host.com/sample.xml');
The Send
method has a second optional parameter, which indicates that the connection should be terminated right after getting the contents of the document. By default, it's set to "true
", i.e. terminate connection.
Parsing an XML Document
Realized in the kXMLHelper
class is a convenient mechanism for parsing an XML document. The first step is to create an object of the class.
$xml_helper =& $this->Application->recallObject('kXMLHelper'); /* @var $xml_helper kXMLHelper */
Then, to start the parsing of the XML document retrieved earlier.
$root_node =& $xml_helper->Parse($file_contents);
A tree structure of objects will be returned as a result, in which all objects are connected using links. The contents of each object of the kXMLNode
class looks like this:
kxmlnode Object ( [Name] => xml_element_name [Attributes] => Array ( [1st_attribute_name] => 1st_attribute_value [2nd_attribute_name] => 2nd_attribute_value ... ) [Children] => Array ( [0] => kxmlnode Object [1] => kxmlnode Object ... ) [Data] => text_value_that_this_XML_element_encapsulates [firstChild] => kxmlnode Object [lastChild] => kxmlnode Object [Parent] => kxmlnode Object [Position] => 1 )
The below description of the contents of an object of the kXMLNode class will be based on the example at the beginning of the article. |
The parent (root) object will be assigned to the $root_node
variable, i.e. the xml-element object "our_document
". The "Children
" (private) attribute contains an array of all child elements of the current element. In this example, these are the two elements "some_tag
" and "planet_earth
". The last one has two "continent
" child elements. It's import to understand that array elements are the same as other objects, they can themselves have child elements, etc.
Each element has a Position
attribute. This is its order in the elements (same level elements, for example - "country" Canada and "country" USA). The "firstChild
" and "lastChild
" elements contain the first and last (from the point of view of their Position
) child elements, respectively.
For further processing of received information the kXMLNode
class methods and attributes are used.
Практическое использование kXMLHelper
Ниже приведён код, который распечатает все страны описанного выше XML-документа.
$root_node =& $xml_helper->Parse($xml_data); /* @var $root_node kXMLNode */ // Getting first continent node $continent_node =& $root_node->FindChild('continent'); // Cycling through it and all the rest continent nodes do { // Getting first country node $country_node =& $continent_node->firstChild; // Cycling through it and all the rest continent nodes do { echo $continent_node->Attributes['ID'] . ' - ' . trim($continent_node->Data) . ': ' . $country_node->Attributes['ID'] . ' - ' . trim($country_node->Data) . '<br/>'; } while ($country_node =& $country_node->NextSibling()); } while ($continent_node =& $continent_node->NextSibling());
В переменной $continent_node
сохраняется первый найденный объект "continent
", т.е. - "North America
". В первом цикле перебираются континенты. Для перехода к элементу того же уровня используется метод NextSibling
(есть противоположный ему метод PrevSibling
). Из континента выбирается первая страна. Внутренний цикл перебирает все страны данного континента и делает вывод в приведённом ниже формате. Как можно заметить, текстовое значение элементов доступно через атрибут "Data
".
1 - North America: 1 - Canada 1 - North America: 2 - USA 2 - Europe: 1 - Estonia 2 - Europe: 2 - Latvia 2 - Europe: 3 - Lithuania
Методы класса "kXMLNode"
Ниже приведены public методы класса kXMLNode
. Все методы рассчитаны на чтение данных, но не на их запись.
метод | описание |
---|---|
&FindChild($name)
| Возвращает первый встретившийся элемент-потомок с указанным именем. Работает рекурсивно, до самого последнего уровня. |
FindChildValue($name, $attr=null)
| Возвращает либо значение элемента-потомка (если задано только его имя), либо один из атрибутов (если явно указан). |
&GetChildByPosition($position)
| Возвращает дочерний элемент, который находится по указанной позиции. |
GetXML()
| Генерирует и возвращает XML-документ, построенный от текущего элемента. Актуально при предыдущем изменении структуры и не только. |