XML - схема. Лекция 2

Содержание

Слайд 2

DTD для XML Schemas schema Определение типа complexType simpleType complexContent simpleContent

DTD для XML Schemas

schema
Определение типа
complexType
simpleType
complexContent
simpleContent
extension
restriction
Определение элементов
element
group
all
choice
sequence
Открытый контент
any
anyAttribute

Определение атрибутов
attribute


attributeGroup
Cсылочные механизмы
unique
key
keyref
selector
field
Комбинационные механизмы
include
import
redefine
notation
Передача инструкций или документация
annotation
appinfo
documentation

Лекция 3/16

Слайд 3

Элемент Schemas ((simpleType | complexType | element | attribute | attributeGroup

Элемент Schemas

((simpleType

| complexType | element | attribute | attributeGroup | group | notation), (annotation)*)* )>
targetNamespace %URIref; #IMPLIED
version CDATA #IMPLIED
xmlns:xs %URIref; #FIXED http://www.w3.org/2001/XMLSchema'
xmlns CDATA #IMPLIED
finalDefault %complexDerivationSet; ''
blockDefault %blockSet; ''
id ID #IMPLIED
elementFormDefault %formValues; 'unqualified'
attributeFormDefault %formValues; 'unqualified'
xml:lang CDATA #IMPLIED
%schemaAttrs;>




Слайд 4

Атрибуты элемента schema id ID #IMPLIED finalDefault %complexDerivationSet; finalDefault: задание значения

Атрибуты элемента schema

id ID #IMPLIED
finalDefault %complexDerivationSet;
finalDefault: задание значения по умолчанию
blockDefault %blockSet;
blockDefault:

задание значения по умолчанию
elementFormDefault %formValues; 'unqualified'
attributeFormDefault %formValues; 'unqualified‘
Допустимые значения для elementFormDefault (attributeFormDefault) - qualified и unqualified. Значение по умолчанию - unqualified.
Если elementFormDefault (attributeFormDefault)="unqualified”, то все локальные элементы (атрибуты) в документе не должны быть связаны с пространствами имен.
Если elementFormDefault (attributeFormDefault) ="qualified" то все локальные элементы (атрибуты) в документе должны быть связаны с пространствами имен.
Слайд 5

Что использовать qualified или unqualified? В документе, независимо от того определяете

Что использовать qualified или unqualified?

В документе, независимо от того определяете Вы

все элементы или только глобальные, все элементы разбираются.
В чем различие при задании значения elementFormDefault “qualified” или “unqualified”?
Cлучай 1: elementFormDefault="unqualified" и в документе определены только глобальные элементы
Pro: спрятана сложность пространства имен в схеме
Contra: если схема модифицируется, т.е. локальные декларации делаются глобальными, то все документы конфликтуют; пользователю надо помнить о том какие элементы глобальные и какие локальные.
Случай 2: element elementFormDefault="qualified" и в документе определены все элементы
Pro: если в схеме локальные элементы преобразуются в глобальные, то нет конфликта документов; пользователю не надо помнить о том какие элементы глобальные, а какие локальные; для целей copyright желательно показывать пространства имен в документе.
Contra: показывается сложная структура пространств имен в документе
Слайд 6

Элемент составной тип name %NCName; #IMPLIED id ID #IMPLIED abstract %boolean;

Элемент составной тип

choice | sequence | group)?, ((attribute | attributeGroup)*,anyAttribute?)))))>
name %NCName; #IMPLIED
id ID #IMPLIED
abstract %boolean; #IMPLIED
final %complexDerivationSet; #IMPLIED
block %complexDerivationSet; #IMPLIED
mixed (true | false) 'false'
%complexTypeAttrs;>
block: используется для запрещения типу элемента быть замененным производным типом
abstract: используется для создания порождающих типов, которые в документе не используются.
Слайд 7

Запрещение задания типов Иногда при создании типа необходимо запретить ему быть

Запрещение задания типов

Иногда при создании типа необходимо запретить ему быть базовым

типом для создания иных типов или только расширения или ограничения.
Причина: «Например, можно создать complexType и сделать его доступным для использования другим. Однако, может возникнуть потребность запрета на его изменение, скажем для случая копирайта."

Тип не может быть редуцирован или расширен
Тип не может быть редуцирован
Тип не может быть расширен

Атрибуты элемента complexType

Слайд 8

mixed Содержанием элементов в документе могут быть элементы или данные Элемент,

mixed

Содержанием элементов в документе могут быть элементы или данные
Элемент, содержащий смесь

элементов и (строковых) данных, называется смешанным контентом.
Смешанный контент может иметь много приложений, Например, XSLT использует смешанный контент в правилах для шаблонов


Название книги:

Автор книги:


Заметим, что содержание
xsl:элемента является смесью строковых данных и элементов.

Атрибуты элемента complexType

Слайд 9

Элементы complexContent, simpleContent, extension mixed (true | false) #IMPLIED id ID

Элементы complexContent, simpleContent, extension


mixed (true |

false) #IMPLIED
id ID #IMPLIED
%complexContentAttrs;>

id ID #IMPLIED
%simpleContentAttrs;>

base %QName; #REQUIRED
id ID #IMPLIED
%extensionAttrs;>
Слайд 10

Элемент element (unique | key | keyref)*)> name %NCName; #IMPLIED id

Элемент element

(unique | key |

keyref)*)>
name %NCName; #IMPLIED
id ID #IMPLIED
ref %QName; #IMPLIED
type %QName; #IMPLIED
minOccurs %nonNegativeInteger; #IMPLIED
maxOccurs CDATA #IMPLIED
nillable %boolean; #IMPLIED
substitutionGroup %QName; #IMPLIED
abstract %boolean; #IMPLIED
final %complexDerivationSet; #IMPLIED
block %blockSet; #IMPLIED
default CDATA #IMPLIED
fixed CDATA #IMPLIED
form %formValues; #IMPLIED
%elementAttrs;>
Слайд 11

Атрибуты элемента Element nillable %boolean; #IMPLIED abstract %boolean; #IMPLIED final %complexDerivationSet;

Атрибуты элемента Element

nillable %boolean; #IMPLIED
abstract %boolean; #IMPLIED
final %complexDerivationSet; #IMPLIED

block %blockSet; #IMPLIED
form %formValues; #IMPLIED
form: используется для отмены elementFormDefault (определенном в элементе schema). Принимает два значения - qualified или unqualified. Если значение для form - qualified, то элемент должен быть отнесен к пространству имен в экземпляре документа.
abstract: используется для указания на то, что элемент является собирательным именем для группы подстановки substitutionGroup. По умолчанию принимает значение false.
block: используется для запрещения замены данного элемента на элемент из группы подстановки или запрещения типу элемента быть замененным производным типом.
nillable: указывает на то, что значение элемента в документе может быть пусто, что указывается в значении атрибута xsi:null. Значение по умолчанию false.
Слайд 12

Элемент группа элементов (group), неупорядоченный список (all) name %NCName; #IMPLIED ref

Элемент группа элементов (group), неупорядоченный список (all)

| choice | sequence)?)>
name %NCName; #IMPLIED
ref %QName; #IMPLIED
minOccurs %nonNegativeInteger; #IMPLIED
maxOccurs CDATA #IMPLIED
id ID #IMPLIED
%groupAttrs;>

minOccurs (1) #IMPLIED
maxOccurs (1) #IMPLIED
id ID #IMPLIED
%allAttrs;>
Слайд 13

Элементы (выбор и упорядоченный список (сhoice, sequence) minOccurs %nonNegativeInteger; #IMPLIED maxOccurs

Элементы (выбор и упорядоченный список (сhoice, sequence)

group| (choice | sequence) | any)*)>
minOccurs %nonNegativeInteger; #IMPLIED
maxOccurs CDATA #IMPLIED
id ID #IMPLIED
%choiceAttrs;>

minOccurs %nonNegativeInteger; #IMPLIED
maxOccurs CDATA #IMPLIED
id ID #IMPLIED
%sequenceAttrs;>
Слайд 14

Элементы произвольный элемент и произвольный атрибут (any, anyAttribute) namespace CDATA '##any'

Элементы произвольный элемент и произвольный атрибут (any, anyAttribute)


namespace CDATA '##any'
processContents (skip|lax|strict) 'strict'
minOccurs %nonNegativeInteger; '1'
maxOccurs CDATA '1'
id ID #IMPLIED
%anyAttrs;>
##any - - любой не конфликтующий корректный XML контент
##other - - любой не конфликтующий корректный XML контент из пространства имен иного чем targetNamespace
##local - - любой не проверяемый не конфликтующий корректный XML контент/атрибут-->

namespace CDATA '##any'
processContents (skip|lax|strict) 'strict'
id ID #IMPLIED
%anyAttributeAttrs;>
пространство имен специфицируется также как 'any'
simpleType only if no type|ref attribute
ref not allowed at top level, name iff at top level
wfxml спецификация контента (well-formed XML)
Слайд 15

Элемент атрибут (attribute) name %NCName; #IMPLIED id ID #IMPLIED ref %QName;

Элемент атрибут (attribute)


name %NCName; #IMPLIED

id ID #IMPLIED
ref %QName; #IMPLIED
type %QName; #IMPLIED
use (prohibited|optional|required) #IMPLIED
default CDATA #IMPLIED
fixed CDATA #IMPLIED
form %formValues; #IMPLIED
%attributeAttrs;>
type и ref взаимно исключаемы. name и ref взаимно исключаемы, допустимо либо одно, либо другое. Значение по умолчанию для use - optional. default и fixed взаимно исключаемы. type и simpleType взаимно исключаемы
Слайд 16

Элемент группа атрибутов (attributeGroup) name %NCName; #IMPLIED id ID #IMPLIED ref %QName; #IMPLIED %attributeGroupAttrs;>

Элемент группа атрибутов (attributeGroup)


name %NCName; #IMPLIED
id ID #IMPLIED
ref %QName; #IMPLIED
%attributeGroupAttrs;>
Слайд 17

element complexType schema sequence http://www.w3.org/2001/XMLSchema string integer boolean BookStore Book Title

element

complexType

schema

sequence

http://www.w3.org/2001/XMLSchema

string

integer

boolean

BookStore

Book

Title

Author

Date

ISBN

Publisher

http://www.books.org (targetNamespace)

Это словарь с помощью которого
XML схема обеспечивают создание нового

словаря
Слайд 18

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> BookStore.xsd xsd = Xml-Schema Definition


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















BookStore.xsd

xsd = Xml-Schema Definition

Слайд 19

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> ISBN, Publisher)>


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>

























ISBN, Publisher)>


Слайд 20

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Все XML схемы имеют тег "schema" В качестве корневого элемента.


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















Все XML схемы
имеют тег "schema"
В качестве корневого
элемента.

Слайд 21

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Элементы и типы данных, используемые для построения схем


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















Элементы и типы данных, используемые для построения схем
- schema
- element
- complexType
- sequence
- string
принадлежат пространству имен
http://…/XMLSchema

Слайд 22

element complexType schema sequence http://www.w3.org/2001/XMLSchema Пространство имен XMLSchema string integer boolean

element

complexType

schema

sequence

http://www.w3.org/2001/XMLSchema

Пространство имен XMLSchema

string

integer

boolean

Слайд 23

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Указывает на то, что элементы, определяемые схемой -


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















Указывает на то, что элементы, определяемые схемой
- BookStore
- Book
- Title
- Author
- Date
- ISBN
- Publisher
принадлежат пространству имен
http://www.books.org

Слайд 24

BookStore Book Title Author Date ISBN Publisher http://www.books.org (targetNamespace) Пространство имен Books (targetNamespace)

BookStore

Book

Title

Author

Date

ISBN

Publisher

http://www.books.org (targetNamespace)

Пространство имен Books (targetNamespace)

Слайд 25

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Вот ссылка на декларацию элемента Book. В каком


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















Вот ссылка на декларацию элемента Book.
В каком пространстве имен Book? Так как приставка отсутствует, то элемент Book в пространстве имен по умолчанию, т.е. targetNamespace! T.о., это ссылка на декларацию элемента Book в данной схеме.

Пространство
имен по умолчанию
http://www.books.org
совпадает с
targetNamespace!

Слайд 26

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Это директива любому элементу соответствующему данной схеме: Любые


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



ref="Book" minOccurs="1" maxOccurs="unbounded"/>




















Это директива любому элементу соответствующему данной схеме:
Любые элементы, используемые в документе, которые декларированы в этой схеме, должны быть специфицированы по пространствам имен.

Слайд 27

Ссылка на схему в XML документе xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.books.org BookStore.xsd"> My Life

Ссылка на схему в XML документе


xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.books.org

BookStore.xsd">

My Life and Times
Paul McCartney
July, 1998
94303-12021-43892
McMillin Publishing

...

Использование пространства имен по умолчанию указывает парсеру на то, что все элементы документа относятся к пространству имен http://www.books.org.
schemaLocation указывает парсеру на то, что в пространстве имен http://www.books.org определена схема BookStore.xsd (i.e., schemaLocation содержит пару значений).
указывает парсеру на то, что атрибут schemaLocation определен в пространстве имен XMLSchema-instance.

1

2

3

Слайд 28

Ссылка на схему в XML документе BookStore.xml BookStore.xsd targetNamespace="http://www.books.org" schemaLocation="http://www.books.org BookStore.xsd"

Ссылка на схему в XML документе

BookStore.xml

BookStore.xsd

targetNamespace="http://www.books.org"

schemaLocation="http://www.books.org
BookStore.xsd"

- определяет элементы в пространстве

имен http://www.books.org

- использует элементы из пространства имен http://www.books.org

Схема определяет новый словарь. Документы используют этот словарь.

Слайд 29

Многоуровневость проверки BookStore.xml BookStore.xsd XMLSchema.xsd (schema-for-schemas) Проверка на то, что xml

Многоуровневость проверки

BookStore.xml

BookStore.xsd

XMLSchema.xsd
(schema-for-schemas)

Проверка на то, что xml документ
Соответствует правилам, описанным в
BookStore.xsd

Проверяем, что

BookStore.xsd является корректной схемой, i.e., он соответствует правилам описанным в schema-for-schemas
Слайд 30

Значения по умолчанию для minOccurs и maxOccurs Значение по умолчанию для

Значения по умолчанию для minOccurs и maxOccurs

Значение по умолчанию для minOccurs

- "1"
Значение по умолчанию для maxOccurs - "1"



Equivalent!

Слайд 31

targetNamespace="http://www.books.org" xmlns:bk="http://www.books.org" elementFormDefault="qualified"> Заметим, что http://…/XMLSchema является пространством имен по умолчанию.


targetNamespace="http://www.books.org"
xmlns:bk="http://www.books.org"
elementFormDefault="qualified">



ref="bk:Book" maxOccurs="unbounded"/>




















Заметим, что
http://…/XMLSchema
является пространством имен по умолчанию.
Следовательно, нет необходимости использовать приставки для
- schema
- element
- complexType
- sequence
- string

Слайд 32

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Все декларации элементов помещены внутрь и исчезла возможность


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



name="Book" maxOccurs="unbounded">














Все декларации элементов помещены внутрь и исчезла возможность ссылаться на эти элементы. Схема стала более компактной!

Такой способ создания схемы – вкладывание во внутрь – называют матрешкой

Линейные декларации элемента

Слайд 33

Анонимные типы targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified">

Анонимные типы


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">


















Слайд 34

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Поименованный тип Преимущество расщепления декларации элемента Book и


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">



name="Book" type="BookPublication" maxOccurs="unbounded"/>













Поименованный тип

Преимущество расщепления декларации элемента Book и введения поименованного типа состоит в том, что он может использоваться другими элементами.

Поименованные типы

Слайд 35

Элемент A ссылается на complexType foo. Элемент A содержит декларацию complexType

Элемент A ссылается на
complexType foo.

Элемент A содержит декларацию complexType
внутри своей декларации.

Заметим,

что:







эквивалентно:








Слайд 36

Атрибут type или дочерний элемент complexType Декларация элемента может иметь или

Атрибут type или дочерний элемент complexType

Декларация элемента может иметь или атрибут

type, или дочерний элемент complexType.






Слайд 37

Декларация элементов. Резюме. Простой тип (e.g., xsd:string) или a complexType (e.g.,

Декларация элементов. Резюме.


Простой тип
(e.g., xsd:string)
или
a complexType
(e.g., BookPublication)

name="name" minOccurs="int" maxOccurs="int">




1

2

Неотриц. целое

Неотрицательное целое или "unbounded"

Note: minOccurs и maxOccurs можно использовать в локальных декларациях элементов

Слайд 38

Типы данных Встроенные типы данных (i.e., известные типы для парсеров схемы

Типы данных

Встроенные типы данных (i.e., известные типы для парсеров схемы )
Этот

тип данных используется для представления дня (год-месяц-день)
Элементы с типом date должны иметь форму: CCYY-MM-DD
диапазон CC : 00-99
диапазон YY : 00-99
диапазон MM: 01-12
диапазон DD:
01-28 если месяц 2
01-29 если месяц 2 и gYear высокосный
01-30 если месяц 4, 6, 9 или 11
01-31 если месяц 1, 3, 5, 7, 8, 10 или 12
Example: 1999-05-31 представляет May 31, 1999
Слайд 39

Тип данных gYear Встроенный тип (Григорианский календарь) Элементы с типом gYear

Тип данных gYear

Встроенный тип (Григорианский календарь)
Элементы с типом gYear должны иметь

форму : CCYY
диапазон CC : 00-99
диапазон YY : 00-99
Пример: 1999 указывает год gYear 1999
Слайд 40

targetNamespace="http://www.books.org" xmlns="http://www.books.org" elementFormDefault="qualified"> Определение нового типа данных ISBNType. Декларация Date с


targetNamespace="http://www.books.org"
xmlns="http://www.books.org"
elementFormDefault="qualified">


value="\d{1}-\d{5}-\d{3}-\d{1}"/>






















Определение нового типа данных ISBNType.

Декларация Date с типом gYear, и ISBN с типом ISBNType
(defined above)

Слайд 41

Продекларирован новый тип ISBNType. Он является ограничительной формой типа string. Элементы








Продекларирован

новый тип ISBNType. Он является ограничительной формой типа string. Элементы такого типа должны соответствовать следующим образцам:
- Первый шаблон: 1 цифра - 5 цифр - 3 цифры - 1 цифра
- Второй шаблон: 1 - 3 - 5 - 1
- Третий шаблон: 1 - 2 - 6 - 1

Эти образцы специфицируются с помощью Regular Expressions.

Слайд 42

Эквивалентные выражения Вертикальная линия означает “или"

Эквивалентные выражения













Вертикальная линия означает “или"

Слайд 43

Встроенные типы данных Примитивы типов данных String boolean decimal float double

Встроенные типы данных

Примитивы типов данных
String
boolean
decimal
float
double
duration
dateTime
time
date
gYearMonth
gYear
gMonthDay

Атомные, встроенные
"Hello World"
{true, false, 1, 0}
7.08
12.56E3,

12, 12560, 0, -0, INF, -INF, NAN
12.56E3, 12, 12560, 0, -0, INF, -INF, NAN
P1Y2M3DT10H30M12.3S
format: CCYY-MM-DDThh:mm:ss
format: hh:mm:ss.sss
format: CCYY-MM-DD
format: CCYY-MM
format: CCYY
format: --MM-DD

Замечание: 'T' – разделитель дня от часов
INF = infinity
NAN = not-a-number

Слайд 44

Встроенные типы данных Примитивы типов данных gDay gMonth hexBinary base64Binary anyURI

Встроенные типы данных

Примитивы типов данных
gDay
gMonth
hexBinary
base64Binary
anyURI
Qname
NOTATION

Атомные, встроенные
format: ---DD (note the

3 dashes)
format: --MM--
a hex string
a base64 string
http://www.xfront.com
a namespace qualified name
a NOTATION from the XML spec
Слайд 45

Встроенные типы данных Производные типы данных normalizedString Token language IDREFS ENTITIES

Встроенные типы данных

Производные типы данных
normalizedString
Token
language
IDREFS
ENTITIES
NMTOKEN
NMTOKENS
Name
NCName
ID, IDREF
ENTITY
integer
nonPositiveInteger

Подтипы примитивов типов данных
A string

without tabs, line feeds, or carriage returns
String w/o tabs, l/f, leading/trailing spaces, consecutive spaces
any valid xml:lang value, e.g., EN, FR, ...
Должно использоваться только с атрибутами
Должно использоваться только с атрибутами
Должно использоваться только с атрибутами
Должно использоваться только с атрибутами
part (no namespace qualifier)
Должно использоваться только с атрибутами
Должно использоваться только с атрибутами
Должно использоваться только с атрибутами
456
negative infinity to 0
Слайд 46

Встроенные типы данных Производные типы negativeInteger Long int short byte nonNegativeInteger

Встроенные типы данных

Производные типы
negativeInteger
Long
int
short
byte
nonNegativeInteger
unsignedLong
unsignedInt
unsignedShort
unsignedByte
positiveInteger

Подтипы примитивов типов данных
negative infinity to

-1
-9223372036854775808 to 9223372036854775807
-2147483648 to 2147483647
-32768 to 32767
-127 to 128
0 to infinity
0 to 18446744073709551615
0 to 4294967295
0 to 65535
0 to 255
1 to infinity

Note: следующие типы можно использовать с атрибутами:
ID, IDREF, IDREFS, NMTOKEN, NMTOKENS, ENTITY, and ENTITIES.

Слайд 47

или ? Когда использовать элемент complexType или simpleType? Используйте элемент complexType

или ?

Когда использовать элемент complexType или simpleType?
Используйте элемент complexType тогда,

когда хотите определить дочерние элементы и/или атрибуты элемента
Используйте элемент simpleType тогда, когда хотите создать новый тип который модифицирует встроенный тип данных (string, date, gYear, etc)
Слайд 48

Элемент с простым типом Пример. Создать декларацию элемента elevation. Декларировать элемент

Элемент с простым типом

Пример. Создать декларацию элемента elevation.
Декларировать элемент elevation

как целое в интервале -1290 до 29035
5240
Один из способов декларации:







Слайд 49

Элемент с простым типом Другой способ: Определение (анонимное) simpleType внутри элемента.

Элемент с простым типом

Другой способ:








Определение (анонимное) simpleType внутри элемента.
Недостаток такого подхода состоит в том, что данный simpleType нельзя использовать в других элементах.

Слайд 50

Декларация элементов. Резюме. … 1 2 … 3

Декларация элементов. Резюме.







1

2








3