In-Portal Developers Guide

This is a wiki-based Developers Guide for In-Portal Open Source CMS. The purpose of this guide is to provide advanced users, web developers and programmers with documentation on how to expand, customize and improve the functionality and the code the In-Portal software. Please consider contributing to our documentation writing effort.

K4:KXMLHelper

From In-Portal Developers Guide

Jump to: navigation, search
m (1 версия)
Current revision (01:19, 28 November 2010) (view source)
(Side-box)
 
(7 intermediate revisions not shown.)
Line 1: Line 1:
{{toc | category = Вспомогательные классы | sortkey = 002.001}}
{{toc | category = Вспомогательные классы | sortkey = 002.001}}
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! -->
<!-- Пишите ПОСЛЕ этой строки, пожалуйста. Ничего не стирать! -->
-
<code>XML</code> - удобный формат описания данных, который строится по древовидной структуре. Каждый элемент может содержать значение и/или другие элементы. Текст внутри элемента может чередоваться с дочерними элементами, но он всё равно будет расценен как единое значение. Кроме того, у каждого элемента могут быть заданы атрибуты. Всё выше описанное отражено в ниже приведённом примере (пусть это будет файл "<code>sample.xml</code>"):
+
<code>XML</code> 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 "<code>sample.xml</code>"):
<source lang="xml">
<source lang="xml">
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
Line 34: Line 34:
</source>
</source>
-
== Блок CDATA ==
+
== The CDATA Block ==
-
Если требуется указать в качестве содержания одного из элементов символы, которые могут помешать корректной разборке XML документа, то нужно содержание элемента заключать в блок CDATA. К ряду символов таких символов относятся символы "<code>></code>", "<code><</code>" и "<code>&</code>". Синтаксис блока <code>CDATA</code> выглядит следующим образом:
+
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 "<code>></code>", "<code><</code>" и "<code>&</code>". The syntax of a <code>CDATA</code> block looks like this:
<source lang="xml">
<source lang="xml">
Line 41: Line 41:
</source>
</source>
-
Данные внутри блока <code>CDATA</code> не должны содержать последовательность "<code>]]></code>", т.к. она будет воспринята как окончание данного блока. Если задание такой последовательности символов необходимо, следует воспользоваться следующим подходом:
+
Data inside a CDATA block should not contain "<code>]]></code>" because it will considered the end of the block. If it's absolutely necessary to have "<code>]]></code>" then the following approach will work:
<source lang="xml">
<source lang="xml">
Line 47: Line 47:
</source>
</source>
-
В выше приведённом примере данные разбиты на два фрагмента и каждый из них заключён в свой блок <code>CDATA</code>. Особенно удобно применение <code>CDATA</code> в случае, когда нужно написать <code>XML</code>, который будет показан пользователю, но не обработан при разборке XML документа.
+
In the above example, the contents are separated into two parts, each of which is inside a <code>CDATA</code> block. It's especially convenient to use <code>CDATA</code> in the situation where <code>XML</code> needs to be written to show to a user, but won't be processed when parsing the XML document.
-
== Получение XML документа ==
+
== Getting an XML Document ==
-
Перед тем, как разбирать <code>XML</code> документ, содержащийся в файле, его нужно сначала прочитать.
+
Before parsing an <code>XML</code> document, it has to be received.
-
=== Получение локального файла ===
+
=== Getting a Local File ===
-
Для получения локального файла (т.е. находящегося на том-же компьютере, что и сам сайт) следует использовать стандартную функцию [http://php.prod.intechnic.lv/manual/en/function.file-get-contents.php file_get_contents]. Данная функция возвращает содержание файла, путь к которому передан в качестве первого её аргумента.
+
To get a local file (i.e. located on the same computer as the site), the standard [http://us.php.net/manual/en/function.file-get-contents.php file_get_contents] function can be used. This function returns the contents of file, the path of which is passed as its first argument.
<source lang="php">
<source lang="php">
Line 59: Line 59:
</source>
</source>
-
=== Получение удалённого файла ===
+
=== Getting a Remote File ===
-
Функция [http://php.prod.intechnic.lv/manual/en/function.file-get-contents.php file_get_contents] также позволяет получать содержимое файлов, находящихся на удалённых ресурсах. Однако, в целях безопасности, на сервере может быть запрещена эта возможность. Поэтому настоятельно рекомендуется получать удалённый файл при помощи стандартного класса K4 - <code>kCurlHelper</code>.
+
The [http://us.php.net/manual/en/function.file-get-contents.php 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 <code>kCurlHelper</code> class to retrieve remote files.
<source lang="php">
<source lang="php">
Line 69: Line 69:
</source>
</source>
-
У метода <code>Send</code> также есть второй необязательный параметр, который указывает на то, что нужно закрывать соединение сразу после получения содержания документа. По умолчанию он равен "<code>true</code>", т.е. закрывать соединение.
+
The <code>Send</code> 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 "<code>true</code>", i.e. terminate connection.
-
== Разборка XML документа ==
+
== Parsing an XML Document ==
-
В классе <code>kXMLHelper</code> реализован удобный механизм разбора XML документа. Сначала следует создать экземпляр класса.
+
Realized in the <code>kXMLHelper</code> class is a convenient mechanism for parsing an XML document. The first step is to create an object of the class.  
<source lang="php">
<source lang="php">
Line 79: Line 79:
</source>
</source>
-
Далее, начать обработку полученного ранее XML документа.
+
Then, to start the parsing of the XML document retrieved earlier.
<source lang="php">
<source lang="php">
Line 85: Line 85:
</source>
</source>
-
В результате будет возвращена древовидная структура объектов, в которой все объекты связаны при помощи ссылок. Содержимое каждого объекта класса <code>kXMLNode</code> выглядит так:
+
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 <code>kXMLNode</code> class looks like this:
<source lang="php">
<source lang="php">
Line 110: Line 110:
</source>
</source>
-
{{TipBox|Всё ниже приведённое описание содержания объекта класса kXMLNode будет основано на примере, приведённом в начале статьи.}}
+
{{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.}}
-
Переменной <code>$root_node</code> будет присвоен родительский (root) объект, т.е. это объект xml-элемента "<code>our_document</code>". Атрибут "<code>Children</code>" (private) содержит массив всех дочерних элементов текущего элемента. В данном примере ими являются два элемента - "<code>some_tag</code>" и "<code>planet_earth</code>". У последнего - два дочерних элемента "<code>continent</code>". Важно понимать, что элементы массива - точно такие же объекты, как и текущий. У них, в свою очередь, могут быть свои дочерние элементы, и так далее.
+
-
У каждого элемента есть атрибут <code>Position</code>. Это - порядковый номер элемента среди соседних элементов (элементов того же уровня, например - "country" Canada и "country" USA). Атрибуты "<code>firstChild</code>" и "<code>lastChild</code>" содержат первый и последний (с точки зрения его <code>Position</code>) дочерний элемент соответственно.
+
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.
-
Для последующей обработки полученной информации используется методы и атрибуты именно класса <code>kXMLNode</code>.
+
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.  
-
== Практическое использование kXMLHelper ==
+
For further processing of received information the <code>kXMLNode</code> class methods and attributes are used.
-
Ниже приведён код, который распечатает все страны описанного выше XML-документа.
+
 
 +
== kXMLHelper in Practice ==
 +
 
 +
The below code prints all of the countries in the above XML-document.
<source lang="php">
<source lang="php">
Line 127: Line 129:
$continent_node =& $root_node->FindChild('continent');
$continent_node =& $root_node->FindChild('continent');
-
// Cycling through it and all the rest continent nodes
+
// Cycling through it and all the rest of the continent nodes
do {
do {
// Getting first country node
// Getting first country node
$country_node =& $continent_node->firstChild;
$country_node =& $continent_node->firstChild;
-
// Cycling through it and all the rest continent nodes
+
// Cycling through it and all the rest of the continent nodes
     do {
     do {
         echo $continent_node->Attributes['ID'] . ' - ' . trim($continent_node->Data) . ': ' . $country_node->Attributes['ID'] . ' - ' . trim($country_node->Data) . '<br/>';
         echo $continent_node->Attributes['ID'] . ' - ' . trim($continent_node->Data) . ': ' . $country_node->Attributes['ID'] . ' - ' . trim($country_node->Data) . '<br/>';
Line 139: Line 141:
</source>
</source>
-
В переменной <code>$continent_node</code> сохраняется первый найденный объект "<code>continent</code>", т.е. - "<code>North America</code>". В первом цикле перебираются континенты. Для перехода к элементу того же уровня используется метод <code>NextSibling</code> (есть противоположный ему метод <code>PrevSibling</code>). Из континента выбирается первая страна. Внутренний цикл перебирает все страны данного континента и делает вывод в приведённом ниже формате. Как можно заметить, текстовое значение элементов доступно через атрибут "<code>Data</code>".  
+
The <code>$continent_node</code> variable stores the first found "<code>continent</code>" object, i.e. - "<code>North America</code>". The first loop goes through the continents. The <code>NextSibling</code> method is used to go to the element of the same level (the counterpart of this method is <code>PrevSibling</code>). The first country is chosen from the continent. The inner loop goes through all countries of a continent and returns them in the below format. Note, the text values of the elements are accessible through the "<code>Data</code>" attribute.  
  1 - North America: 1 - Canada
  1 - North America: 1 - Canada
Line 147: Line 149:
  2 - Europe: 3 - Lithuania
  2 - Europe: 3 - Lithuania
-
== Методы класса "kXMLNode" ==
+
== "kXMLNode" Class Methods ==
-
Ниже приведены public методы класса <code>kXMLNode</code>. Все методы рассчитаны на чтение данных, но не на их запись.
+
Below are public methods of the <code>kXMLNode</code> class. All these methods are for reading data, but not for recording it.  
-
 
+
{| class="prettytable"  
{| class="prettytable"  
-
! метод || описание
+
! Method || Description
|-
|-
| <code>&FindChild($name)</code>
| <code>&FindChild($name)</code>
-
| Возвращает первый встретившийся элемент-потомок с указанным именем. Работает рекурсивно, до самого последнего уровня.
+
| Returns the first element descendant with the given name. Works recursively through to the last level.  
|-
|-
| <code>FindChildValue($name, $attr=null)</code>
| <code>FindChildValue($name, $attr=null)</code>
-
| Возвращает либо значение элемента-потомка (если задано только его имя), либо один из атрибутов (если явно указан).
+
| Returns either the value of the element descendant (if only its name is set) or one of its attributes (if explicitly set).
|-
|-
| <code>&GetChildByPosition($position)</code>
| <code>&GetChildByPosition($position)</code>
-
| Возвращает дочерний элемент, который находится по указанной позиции.
+
| Returns the child element that's located at the given position.
|-
|-
| <code>GetXML()</code>
| <code>GetXML()</code>
-
| Генерирует и возвращает XML-документ, построенный от текущего элемента. Актуально при предыдущем изменении структуры и не только.
+
| Generates and returns an XML-document, built from the current element. Possible not only in the previous structural change.
|}
|}
 +
 +
[[en:{{FULLPAGENAME}}]]
 +
[[ru:K4:Обработка XML документов]]
 +
 +
Translated from: [http://guide.in-portal.org/rus/index.php?title=K4:%D0%9E%D0%B1%D1%80%D0%B0%D0%B1%D0%BE%D1%82%D0%BA%D0%B0_XML_%D0%B4%D0%BE%D0%BA%D1%83%D0%BC%D0%B5%D0%BD%D1%82%D0%BE%D0%B2&oldid=1068 revision 1068]

Current revision

Вспомогательные классы Вспомогательные классы
Статьи в этой категории
  • KXMLHelper

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
)
Image:Tipbox Icon.gif 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 in Practice

The below code prints all of the countries in the above XML-document.

$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 of the continent nodes
do {
	// Getting first country node
	$country_node =& $continent_node->firstChild;
 
	// Cycling through it and all the rest of the 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());

The $continent_node variable stores the first found "continent" object, i.e. - "North America". The first loop goes through the continents. The NextSibling method is used to go to the element of the same level (the counterpart of this method is PrevSibling). The first country is chosen from the continent. The inner loop goes through all countries of a continent and returns them in the below format. Note, the text values of the elements are accessible through the "Data" attribute.

1 - North America: 1 - Canada
1 - North America: 2 - USA
2 - Europe: 1 - Estonia
2 - Europe: 2 - Latvia
2 - Europe: 3 - Lithuania

"kXMLNode" Class Methods

Below are public methods of the kXMLNode class. All these methods are for reading data, but not for recording it.

Method Description
&FindChild($name) Returns the first element descendant with the given name. Works recursively through to the last level.
FindChildValue($name, $attr=null) Returns either the value of the element descendant (if only its name is set) or one of its attributes (if explicitly set).
&GetChildByPosition($position) Returns the child element that's located at the given position.
GetXML() Generates and returns an XML-document, built from the current element. Possible not only in the previous structural change.

Translated from: revision 1068