Основные принципы XML

Проявляемый в настоящее время большой интерес к языку XML объясняется тем, что он предоставляет возможности, позволяющие в текстовой форме описывать структурированные данные. Точнее говоря, XML является метаязыком для создания различных языков разметки, которые способны определять произвольные структуры данных — двоичные данные, записи в базе данных или сценарии. Прежде всего, XML используется в Internet-приложениях при работе браузеров, которые отображают информацию, находящуюся на Web-серверах. При этом пользователю отдельно передаются данные в виде XML-документа, и отдельно — правила интерпретации этих данных для отображения с помощью, например, языков сценариев JScript или VBScript.

Как и HTML, XML является независимым от платформы промышленным стандартом. Полные спецификации XML и связанных с ним языков доступны на официальной странице корпорации World Wide Web Consortium (W3C) по адресу http://www.w3c.org/xml.

Внешне XML-документ похож на HTML-документ, так как XML-элементы также описываются с помощью тегов, то есть ключевых слов. Однако, в отличие от HTML, в XML пользователь может создавать собственные элементы, поэтому набор тегов не является заранее предопределенным. Еще раз повторим, что теги XML определяют структурированную информацию и, в отличие от тегов HTML, не влияют на то, как браузер отобразит эту информацию. Ниже перечислены несколько основных правил формирования корректного XML-документа:

· документ XML состоит из элементов разметки (markup) и непосредственно данных (content);

· все XML-элементы описываются с помощью тегов;

· в заголовке документа с помощью специальных тегов помещается дополнительная информация (используемый язык разметки, его версия и т. д.);

· каждый открывающий тег, который определяет область данных, должен иметь парный закрывающий тег (в HTML некоторые закрывающие теги можно опускать);

· в XML, в отличие от HTML, учитывается регистр символов;

· все значения атрибутов, используемых в определении тегов, должны быть заключены в кавычки;

· вложенность элементов в документе XML строго контролируется.

Рассмотрим теперь структуру и синтаксис WS-файлов, использующих схему WS XML.

Схема WS XML

Синтаксис элементов, составляющих структуру WS-файла, в общем виде можно представить следующим образом:

<element [attribute1="value1" [attribute2="value2" ... ]]>

Содержимое (content)

</element>

Открывающий тег элемента состоит из следующих компонентов:

· открывающей угловой скобки "<";

· названия элемента, написанного строчными буквами;

· необязательного списка атрибутов со значениями (названия атрибутов пишутся строчными буквами, значения заключаются в двойные кавычки);

· закрывающей угловой скобки ">".

Например, тег начала элемента

<script language="JScript">

имеет имя тега script и определяет атрибут language со значением "JScript". Атрибуты предоставляют дополнительную информацию о соответствующем теге или последующем содержимом элемента. В нашем примере атрибут указывает на то, что содержимым элемента является текст сценария на языке JScript.

Закрывающий тег элемента состоит из следующих компонентов:

· открывающей угловой скобки "<";

· символа "/";

· названия элемента, написанного строчными буквами;

· закрывающей угловой скобки ">".

Таким образом, тег конца элемента не имеет атрибутов, например, </script>.

Если у элемента нет содержимого, то он имеет следующий вид:

<element [attribute1="value1" [attribute2="value2" … ]]/>

То есть в этом случае элемент состоит из следующих компонентов:

· открывающей угловой скобки "<";

· названия элемента, написанного строчными буквами;

· необязательного списка атрибутов со значениями (названия атрибутов пишутся строчными буквами, значения заключаются в двойные кавычки);

· символа "/";

· закрывающей угловой скобки ">".

Пример такого элемента:

<script language="JScript" src="tools.js"/>

Представленная в табл. 9.1 схема WS XML — это модель данных, определяющая элементы и соответствующие атрибуты, а также связи элементов друг с другом и возможную последовательность появления элементов. Также эта схема может задавать значения атрибутов по умолчанию.

Таблица 9.1. Схема WS XML
<?XML version="1.0" standalone="yes"?>
  <package>
  <job [id="JobID"]>
  <?job debug="true|false"?>
  <runtime>
    <named name="NamedName" helpstring="HelpString" type="string|boolean|simple" required="true|false" />
    <unnamed name="UnnamedName" helpstring="HelpString" many="true|false" required="true|false" />
    <description> Описание сценария </description>
    <example> Пример запуска сценария </example>
  </runtime>
  <resource id="ResourceID"> Строка или число </resource>
  <object id="ObjID" [classId="clsid:GUID"|progid="ProgID"]/>
<reference [object="ProgID"|guid="typelibGUID"][version="version"]/>
<script language="language" [src="strFileURL"]\>
<script language="language" >
  <![CDATA[
Код сценария
]]>
</script>
</job>
Другие задания
</package>

Таким образом, из табл. 9.1 видно, что:

· элемент <package> может содержать один или несколько элементов <job> ;

· элемент <job> может содержать один или несколько элементов <runtime>, <resource>, <object>, <reference> или <script> ;

· элемент <runtime> может содержать один или несколько элементов <named> и <unnamed>, а также элементы <description> и <example>.

Обязательными для создания корректного сценария являются только элементы <job> и <script>. Сам код сценария всегда располагается внутри элемента <script>.

Опишем теперь элементы XML, использующие в сценариях WSH, более подробно.

Элементы WS-файла

В WS-файл можно вставлять комментарии независимо от разметки XML. Сделать это можно двумя способами: с помощью элемента <!-- --> или элемента <comment>. Например:

<!-- Первый комментарий -->

или

<comment>

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

</comment>

Элементы <?XML?> и <![CDATA[]]>

Эти элементы являются стандартными для разметки W3C XML 1.0. В сценариях WSH они определяют способ обработки WS-файла. Всего существует два режима обработки сценария: нестрогий (loose) и строгий (strict).

При нестрогой обработке (элемент <?XML?> отсутствует) не предполагается выполнение всех требований стандарта XML. Например, не требуется различать строчные и заглавные буквы и заключать значения атрибутов в двойные кавычки. Кроме этого, в процессе нестрогой обработки считается, что все содержимое между тегами <script> и </script> является исходным кодом сценария. Однако при таком подходе может произойти ошибочная интерпретация вложенных в сценарий зарезервированных для XML символов или слов как разметки XML. Например, имеющиеся в коде сценария знаки "меньше" (<) и "больше" (>) могут привести к прекращению разбора и выполнения сценария.

Для того чтобы задать режим строгой обработки сценария, нужно поместить элемент <?XML?> в самой первой строке сценария — никаких других символов или пустых строк перед ним быть не должно. При такой обработке WS-файла нужно четко следовать всем правилам стандарта XML. Код сценария должен быть помещен в секцию CDATA, которая начинается с символов "<![CDATA[" и заканчивается символами "]]>".

Элемент <?job?>

Элемент <?job?> задает режим отладки при выполнении WS-файла. Если значение атрибута debug равно true, то задание может быть выполнено во внешнем отладчике. Если же значение атрибута debug равно false, то отладчик для этого задания применен быть не может. По умолчанию debug имеет значение false.

Элемент <package>

Этот элемент необходим в тех WS-файлах, в которых с помощью элементов <job> определено более одного задания. В этом случае все эти задания должны находиться внутри пары тегов <package> и </package> (см. табл. 3.1). Другими словами, <package> является контейнером для элементов <job>.

Если же в WS-файле определено только одно задание, то элемент <package> можно не использовать.

Элемент <job>

Элементы <job> позволяют определять несколько заданий (независимо выполняющихся частей) в одном WS-файле. Иначе говоря, между тегами <job> и </job> будет находиться отдельный сценарий (который, в свою очередь, может состоять из нескольких частей, написанных, возможно, на разных языках).

У элемента <job> имеется единственный атрибут id, который определяет уникальное имя задания. Например, в сценарии two_jobs.wsf определяются два задания с именами "Task1" и "Task2" (листинг 9.1).

<package>

<job id="Task1">

<!-- Описываем первое задание (id="Task1") -->

<script language="VBScript">

WScript.Echo "Выполняется первое задание (VBScript)"

</script>

</job>

<job id="Task2">

<!-- Описываем второе задание (id="Task1") -->

<script language="JScript">

WScript.Echo("Выполняется второе задание (JScript)");

</script>

</job>

</package>

Листинг 9.1. Файл two_jobs.wsf

Для того чтобы запустить конкретное задание из многозадачного WS-файла, нужно воспользоваться параметром //job:"JobID" в командной строке WSH. Например, следующая команда:

cscript //job:"Task1" two_jobs.wsf

запускает с помощью cscript.exe задание с именем "Task1" из файла two_jobs.wsf.

Замечание

Если параметр //job не указан, то по умолчанию из многозадачного WS-файла запускается первое задание.

Если в WS-файле имеется несколько заданий, то они должны находиться внутри элемента <package>. Элемент <job> является одним из двух обязательных элементов в сценариях WSH с разметкой XML.

Элемент <runtime>

При запуске почти всех стандартных команд или утилит командной строки Windows с ключом /? на экран выводится встроенная справка, в которой кратко описываются назначение и синтаксис этой команды или утилиты. Хорошим тоном считается создание такой справки и для разрабатываемых сценариев WSH. Понятно, что добавление в сценарий функции вывода информации о назначении, синтаксисе и аргументах этого сценария потребовало бы написания довольно большого количества кода: необходимо следить за ключом /? в командной строке, а при добавлении нового параметра командной строки возникнет необходимость изменения функции, отвечающей за вывод информации на экран.

Элемент <runtime> позволяет сделать сценарий самодокументируемым, т. е. в этом случае при задании в командной строке ключа /? на экран будет автоматически выводиться информация об использовании сценария, о его синтаксисе и аргументах (именных и безымянных), а также пример запуска сценария с конкретными значениями аргументов.

При этом сам элемент <runtime> является лишь контейнером, а содержимое для вывода информации хранится в элементах <named>(описание именных параметров командной строки), <unnamed> (описание безымянных параметров командной строки), <description>(описание самого сценария) и <example> (пример запуска сценария), которые находятся внутри <runtime>.

Элемент <named>

С помощью элементов <named> можно описывать (документировать) именные параметры командной строки сценария. В табл. 9.2 приведено описание аргументов элемента <named>.

Таблица 9.2. Аргументы элемента <named>
Аргумент Описание
name Задает имя параметра командной строки
helpstring Строка, содержащая описание параметра командной строки
type Определяет тип параметра командной строки. Может принимать значения "string" (символьный тип), "boolean"(логический тип), "simple" (в сценарий передается только имя параметра без дополнительного значения). По умолчанию используется тип "simple"
required Используется для того, чтобы показать, является ли параметр командной строки обязательным. Может принимать значения "true" (параметр нужно указывать обязательно) и "false" (параметр можно не указывать)

Информация, которая указывается для объявляемого в элементе <named> параметра командной строки, используется только для самодокументируемости сценария и никак не влияет на реальные значения, которые будут указаны в командной строке при запуске сценария. Например, если параметр объявлен как обязательный ( required="true" ), но в действительности не был указан при запуске сценария, то никакой ошибки во время работы не произойдет.

Если для аргумента командной строки сценария указан тип "string", то предполагается, что этот аргумент имеет имя и значение, разделенные символом ":", например:

/Имя:"Андрей Попов" /Возраст:33

Если в качестве типа параметра командной строки используется "simple", то для этого параметра в командной строке указывается только его имя без значения:

/Имя /Возраст

Для того чтобы передать в сценарий аргумент командной строки типа "boolean", нужно после имени этого аргумента указать символ + (соответствует логическому значению "истина" ) или — (соответствует значению "ложь" ). Например:

/Запись+ /ReWrite–

В листинге 9.2 приведен сценарий named.wsf, в котором в блоке <runtime> описываются три именных аргумента командной строки:

· /Имя (обязательный аргумент символьного типа);

· /Компьютер (необязательный аргумент символьного типа);

· /Новый (обязательный аргумент логического типа).

После запуска с помощью wscript.exe в сценарии named.wsf сначала вызывается метод WScript.Arguments.Usage, в результате чего на экран выводится диалоговое окно с информацией о сценарии и параметрах командной строки. Затем в сценарии проверяется, какие именно аргументы командной строки были подставлены при запуске и выделяются значения этих аргументов. Для этого создается объект WshNamed, являющийся коллекцией именных аргументов командной строки, и используется метод Exists этого объекта.

Значением параметра /Новый является константа логического типа ( true или false ), поэтому для формирования строки, соответствующей этому значению, используется условный оператор языка JScript:

//Проверяем, существует ли аргумент /Новый

if (objNamedArgs.Exists("Новый"))

//Получаем с помощью условного оператора значение

//логического аргумента /Новый

s+="Новый пользователь: "+(objNamedArgs("Новый") ? "Да" : "Нет");

<job id="Named">

<runtime>

<description>

Имя: named.wsf

</description>

<named

name="Имя"

helpstring="Имя пользователя"

type="string"

required="true"

/>

<named

name="Компьютер"

helpstring="Имя рабочей станции"

type="string"

required="false"

/>

<named

name="Новый"

helpstring="Признак того, что такого пользователя раньше не было"

type="boolean"

required="true"

/>

</runtime>

 

<script language="JScript">

var objNamedArgs,s;

//Вызываем метод ShowUsage для вывода на экран описания сценария

WScript.Arguments.ShowUsage();

//Создаем объект WshNamed — коллекция именных аргументов сценария

objNamedArgs= WScript.Arguments.Named;

s="";

//Проверяем, существует ли аргумент /Имя:

if (objNamedArgs.Exists("Имя"))

//Получаем значение символьного аргумента /Имя

s+="Имя: "+objNamedArgs("Имя")+"\n";

//Проверяем, существует ли аргумент /Компьютер:

if (objNamedArgs.Exists("Компьютер"))

//Получаем значение символьного аргумента /Компьютер

s+="Машина: "+objNamedArgs("Компьютер")+"\n";

//Проверяем, существует ли аргумент /Новый

if (objNamedArgs.Exists("Новый"))

//Получаем с помощью условного оператора значение

//логического аргумента /Новый

s+="Новый пользователь: "+(objNamedArgs("Новый") ? "Да" : "Нет");

//Выводим полученные строки на экран

WScript.Echo(s);

</script>

</job>

Листинг 9.2. Файл named.wsf

Элемент <unnamed>

С помощью элементов <unnamed> можно описывать (документировать) безымянные параметры командной строки сценария. В табл. 9.3 приведено описание аргументов элемента <unnamed>.

Таблица 9.3. Аргументы элемента <unnamed>
Аргумент Описание
name Задает имя, которое будет указано для описываемого параметра командной строки при выводе информации о сценарии
helpstring Строка, содержащая описание параметра командной строки
many Определяет, сколько раз может быть указан безымянный параметр в командной строке. Значение, равное "true"(используется по умолчанию), означает, что безымянный параметр может встретиться в командной строке более одного раза. Значение, равное "false", означает, что безымянный параметр должен быть указан только один раз
required Определяет, является ли безымянный параметр командной строки обязательным. Может принимать значения "true", "on" или 1 (параметр нужно указывать обязательно), "false", "off" или 0 (параметр можно не указывать). Также значением аргумента "required" может быть целое число, которое показывает, сколько раз безымянный параметр должен обязательно быть указан в командной строке

Информация, которая указывается для объявляемого в элементе <unnamed> параметра командной строки, используется, как и в случае элемента <named>, только для самодокументируемости сценария и никак не влияет на реальные значения, которые будут указаны в командной строке при запуске сценария. Например, если безымянный параметр объявлен как обязательный ( required="true" ), но в действительности не был указан при запуске сценария, то никакой ошибки во время работы не произойдет.

Рассмотрим в качестве примера сценарий unnamed.wsf, в который в качестве параметров командной строки должны передаваться расширения файлов, причем обязательно должны быть указаны хотя бы два таких расширения (листинг 9.3).

Для создания информации об использовании этого сценарии создается элемент <unnamed> следующего вида:

<unnamed

name="Расш"

helpstring="Расширения файлов"

many="true"

required=2

/>

После запуска с помощью wscript.exe в сценарии unnamed.wsf сначала вызывается метод WScript.Arguments.Usage, в результате чего на экран выводится диалоговое окно с информацией о сценарии и параметрах командной строки. Затем в сценарии создается коллекция objUnnamedArgs (объект WshUnnamed ), которая содержит все безымянные аргументы командной строки, реально переданные в сценарий:

objUnnamedArgs=WScript.Arguments.Unnamed; //Создаем объект WshUnnamed

После этого определяется общее число реально переданных в сценарий параметров командной строки (свойство length ) и в цикле while организуется перебор всех элементов коллекции objUnnamedArgs.

<job id="Unnamed">

<runtime>

<description>

Имя: unnamed.wsf

</description>

<unnamed

name="Расш"

helpstring="Расширения файлов"

many="true"

required=2

/>

</runtime>

 

<script language="JScript">

var objUnnamedArgs,s;

//Вызываем метод ShowUsage для вывода на экран описания сценария

WScript.Arguments.ShowUsage();

objUnnamedArgs=WScript.Arguments.Unnamed; //Создаем объект WshUnnamed

//Определяем количество безымянных аргументов

s="Передано в сценарий безымянных аргументов: "+objUnnamedArgs.length;

for (i=0; i<=objUnnamedArgs.length-1; i++)

//Формируем строки со значениями безымянных аргументов

s+="\n"+objUnnamedArgs(i);

//Выводим полученные строки на экран

WScript.Echo(s);

</script>

</job>

Листинг 9.3. Файл unnamed.wsf

 

Элемент <description>

Внутри элемента <description> помещается текст (без дополнительных кавычек), описывающий назначение сценария. Как и все элементы внутри <runtime>, этот текст выводится на экран, если сценарий был запущен с ключом /? в командной строке или если в сценарии встретился вызов метода ShowUsage объекта WshArguments. При выводе текста на экран учитываются все имеющиеся в нем пробелы, символы табуляции и перевода строки.

Пример использования элемента <description> и метода ShowUsage представлен в сценарии descrip.wsf (листинг 9.4). Здесь сразу вызывается метод WScript.Arguments.ShowUsage, в результате чего на экран выводится диалоговое окно (в случае запуска сценария с помощью wscript.exe) или просто строки текста (в случае запуска сценария с помощью cscript.exe) с описанием запущенного сценария.

<job id="Descrip">

<runtime>

<description>

Имя: descrip.wsf

Описание: Здесь можно привести дополнительное описание сценария

</description>

</runtime>

<script language="JScript">

//Вызываем метод ShowUsage

WScript.Arguments.ShowUsage();

</script>

</job>

Листинг 9.4. Файл descrip.wsf

Элемент <example>

Внутри элемента <example> приводится текст из одной или нескольких строк, в котором можно описать примеры запуска сценария. Если сценарий был запущен с ключом /? в командной строке или в сценарии встретился вызов метода ShowUsage объекта WshArguments, то этот текст выводится в графическое диалоговое окно (при использовании wscript.exe) или на экран (в консольном режиме при использовании cscript.exe). При выводе текста на экран учитываются все имеющиеся в нем пробелы, символы табуляции и перевода строки, при этом строки из элемента <example> выводятся после строк из элемента <description>.

Пример использования элемента <example> приведен в листинге 9.5.

<job id="Example">

<runtime>

<description>

Имя: example.wsf

Описание: Здесь можно привести дополнительное описание сценария

</description>

<example>

 

Здесь приводится пример запуска сценария

(с параметрами командной строки, например)

</example>

</runtime>

<script language="JScript">

//Вызываем метод ShowUsage

WScript.Arguments.ShowUsage();

</script>

</job>

Листинг 9.5. Файл example.wsf

Элемент <resource>

Элемент <resource> позволяет отделить символьные или числовые константы (ресурсы) от остального кода сценария. Например, таким образом удобно собрать в одном месте строки, которые используются в сценарии для вывода каких-либо стандартных сообщений. Если после этого понадобится изменить сообщения в сценарии (например, перевести их на другой язык), то достаточно будет внести соответствующие корректировки в строки, описанные в элементах <resource>.

Для получения значения ресурса в сценарии нужно вызвать метод getResource, передав в качестве параметра символьный идентификатор ресурса (значение атрибута id).

В листинге 9.6 представлен пример сценария resource.wsf, в котором определяется ресурсная строка с идентификатором "MyName":

<resource id="MyName">

Меня зовут Андрей Попов

</resource>

Значение этого ресурса затем выводится на экран с помощью метода Echo объекта WScript и метода getResource:

WScript.Echo(getResource("MyName"));

<job id="Resource">

<runtime>

<description>

Имя: resource.wsf

Описание: Пример использования в сценарии ресурсных строк

</description>

</runtime>

<resource id="MyName">

Меня зовут Андрей Попов

</resource>

<script language="JScript">

//Выводим на экран значение ресурса "MyName"

WScript.Echo(getResource("MyName"));

</script>

</job>

Листинг 9.6. Файл resource.wsf

Элемент <object>

Элемент <object> предлагает еще один способ создания экземпляра COM-объектов для использования их внутри сценариев. Напомним, что ранее для этого мы использовали методы CreateObject и GetObject объекта WScript, объект ActiveXObject и функцию GetObjectязыка JScript, а также функцию CreateObject языка VBScript. Элемент <object> может заменить эти средства.

Атрибут id в <object> — это имя, применяемое для обращения к объекту внутри сценария. Отметим, что объект, создаваемый с помощью тега <object>, будет глобальным по отношению к тому заданию, в котором он определен. Другими словами, этот объект может использоваться во всех элементах <script>, находящихся внутри элемента <job>, содержащего описание объекта.

Атрибуты classid и progid используются в <object> соответственно для указания глобального кода создаваемого объекта (Globally Unique ID, GUID) или программного кода объекта (Programmic Identifier). Из этих двух необязательных атрибутов может быть указан только один. Например, создать объект FileSystemObject (GUID="0D43FE01-F093-11CF-8940-00A0C9054228") можно двумя способами:

<object id="fso" classid="clsid:0D43FE01-F093-11CF-8940-00A0C9054228"/>

или

<object id="fso" progid="Scripting.FileSystemObject"/>

В обычном js-файле или внутри элемента <script> этот объект мы бы создали следующим образом:

var fso = WScript.CreateObject("Scripting.FileSystemObject");

или

var fso = new ActiveXObject("Scripting.FileSystemObject");

Элемент <reference>

При вызове многих методов внешних объектов, которые используются внутри сценариев, требуется указывать различные числовые или строковые константы, определенные в этих внешних объектах. Например, для того, чтобы открыть текстовый файл с помощью метода OpenTextFile объекта FileSystemObject, может потребоваться указать параметр, который определяет режим ввода/вывода (возможные значения констант ForReading=1, ForWriting=2 и ForAppending=8 ) открываемого файла. Ясно, что запомнить все значения констант различных объектов очень трудно, поэтому при их использовании приходится постоянно обращаться к справочной информации.

К счастью, большинство объектов предоставляет информацию об именах используемых ими констант в своей библиотеке типов, которая регистрируется в системном реестре при установке COM-объекта и может существовать как в виде отдельного файла с расширением tlb, так и в виде части файла с исполняемым кодом объекта. Элемент <reference> как раз обеспечивает доступ к мнемоническим константам, определенным в библиотеке типов объекта (экземпляр объекта при этом не создается).

Для того чтобы воспользоваться константами определенного объекта, нужно в теге <reference> указать программный код этого объекта (атрибут object ) или глобальный код его библиотеки типов (атрибут guid ), а также, при необходимости, номер версии объекта (атрибут version ).

Например, доступ к константам объекта FileSystemObject организуется следующим образом:

<reference object="Scripting.FileSystemObject"/>

После этого в сценариях можно просто использовать константы с именами ForReading или ForAppending, не заботясь об их числовых значениях.

Элемент <script>

Элемент <script> с помощью атрибута language позволяет определить язык сценария ( language="JScript" для языка JScript и language="VBScript" для языка VBScript). Это делает возможным использовать в одном задании сценарии, написанные на разных языках (мультиязычные сценарии), что иногда бывает очень удобно. Предположим, что у вас имеются сценарии на JScript и VBScript, функции которых необходимо объединить. Для этого не нужно переписывать один из сценариев на другой язык — используя WS-файл, можно из сценария JScript спокойно вызывать функции, написанные на VBScript и наоборот!

Атрибут src позволяет подключить к выполняющемуся сценарию внешний файл с другим сценарием. Например, задание элемента

<script language="JScript" src="tools.js"/>

приведет к такому же результату, как если бы содержимое файла tools.js было расположено между тегами <script> и </script>:

<script language="JScript">

Содержимое файла tools.js

</script>

Таким образом, можно выделить код, который должен использоваться в нескольких сценариях, поместить его в один или несколько внешних файлов, а затем по мере необходимости просто подключать с помощью атрибута src эти файлы к другим сценариям.








Дата добавления: 2018-03-01; просмотров: 1214;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.105 сек.