Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Базовые технологии платформы .NET.docx
Скачиваний:
11
Добавлен:
18.08.2019
Размер:
423.24 Кб
Скачать

17.2. Адаптеры потоков

Перейдём к рассмотрению классов-адаптеров для потоков. Классы BinaryReader и BinaryWriter позволяют при помощи своих методов читать и записывать в поток данные примитивных типов и массивов байтов или символов. Вся информация записывается в поток в двоичном представлении. Рассмотрим работу с этими классами на примере типа Student, который может записать свои данные в поток.

public class Student

{

public string Name { get; set; }

public int Age { get; set; }

public double GPA { get; set; } // Grade Point Average

public void SaveBinaryToStream(Stream stream)

{

// конструктор позволяет "обернуть" адаптер вокруг потока

var bw = new BinaryWriter(stream);

// BinaryWriter имеет 18 перегруженных версий метода Write()

bw.Write(Name);

bw.Write(Age);

bw.Write(GPA);

// убеждаемся, что буфер BinaryWriter пуст

bw.Flush();

}

public void ReadBinaryFromStream(Stream stream)

{

var br = new BinaryReader(stream);

// для чтения каждого примитивного типа есть свой метод

Name = br.ReadString();

Age = br.ReadInt32();

GPA = br.ReadDouble();

}

}

Абстрактные классы TextReader и TextWriter дают возможность читать и записывать данные в поток в строковом представлении. От этих классов наследуются классы StreamReader и StreamWriter. Представим методы для работы с данными класса Student с использованием StreamReader и StreamWriter:

public void SaveToStream(Stream stream)

{

var sw = new StreamWriter(stream);

// запись напоминает вывод на консоль (и не случайно)

sw.WriteLine(Name);

sw.WriteLine(Age);

sw.WriteLine(GPA);

sw.Flush();

}

public void ReadFromStream(Stream stream)

{

var sr = new StreamReader(stream);

// читаем данные как строки

Name = sr.ReadLine();

Age = Int32.Parse(sr.ReadLine());

GPA = Double.Parse(sr.ReadLine());

}

18. Основы xml

Расширяемый язык разметки (eXtensible Markup Language, XML) – это способ описания структурированных данных. Структурированными данными называются такие данные, которые обладают заданным набором семантических атрибутов и допускают иерархическое описание. XML-данные содержатся в документе, в роли которого может выступать файл, поток или другое хранилище информации, способное поддерживать текстовый формат.

Любой XML-документ строится по определённым правилам. Ниже перечислены правила, следовать которым обязательно.

1. Единица информации – XML-элемент. XML-документ состоит из XML-элементов. Каждый элемент определяется при помощи имени, открывающего тега и закрывающего тега. Открывающий тег элемента записывается в форме <имя-элемента>, закрывающий тег – в форме </имя-элемента>. Между открывающим и закрывающим тегами размещается содержимое элемента. Если содержимое элемента отсутствует, то элемент может быть записан в форме <имя-элемента /> или <имя-элемента/>.

2. Иерархия элементов. Содержимым XML-элемента может быть текст, пробельные символы (пробелы, табуляции, переводы строки), а также другие XML-элементы. Допускается комбинация указанного содержимого (например, элемент может содержать и текст, и вложенные элементы). Элементы должны быть правильно вложены друг в друга – если элемент A вложен в элемент B, то закрывающий тег </A> должен находиться перед закрывающим тегом </B>.

3. Корневой элемент. В XML-документе всегда должен быть единственный элемент, называемый корневым, никакая часть которого не входит в содержимое любого другого элемента. Иначе говоря, корневой элемент обрамляет все остальные элементы документа.

4. Синтаксис имён элемента. Имена элементов чувствительны к регистру. Имена могут содержать буквы, цифры, дефисы (-), символы подчёркивания (_), двоеточия (:) и точки (.), однако должны начинаться только с буквы или символа подчёркивания. Двоеточие может быть использовано только в специальных случаях – при записи префикса пространства имён. Имена, начинающиеся с xml (вне зависимости от регистра), зарезервированы для нужд XML.

5. Специальные символы. Некоторые символы не могут использоваться в тексте содержимого элементов, так как применяются в разметке документа. Эти символы могут быть обозначены особым образом:

& символ &

< символ <

> символ >

" символ "

' символ '

&#int; Unicode-символ с десятичным кодом int

&#xhex; Unicode-символ с шестнадцатеричным кодом hex

6. Атрибуты элемента. Любой XML-элемент может содержать один или несколько атрибутов, записываемых в открывающем теге. Правила на имена атрибутов накладываются такие же, как и на имена элементов. Имена атрибутов отделяются от их значений символом =. Значение атрибута заключается в апострофы или в двойные кавычки. Если апостроф или двойные кавычки присутствуют в значении атрибута, то для обрамления используются те из них, которые не встречаются в значении. Приведём пример элементов с атрибутами:

<elements-with-attributes>

<one attr="value"/>

<several first="1" second="2" third="3"/>

<apos-quote case1="John's" case2='He said:"Hello, world!"'/>

</elements-with-attributes>

7. Особые части XML-документа. Кроме элементов, XML-документ может содержать XML-декларацию, комментарии, инструкции по обработке, секции CDATA.

XML-документ может начинаться с XML-декларации, определяющей используемую версию XML, кодировку XML-документа и наличие внешних зависимостей (обязательным атрибутом является только версия):

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>

Комментарии размещаются в любом месте документа и записываются в обрамлении <!-- и -->. В тексте комментариев не должна содержаться последовательность из двух знаков дефиса.

XML-документ может содержать инструкции по обработке, несущие информацию для внешних приложений. Инструкции по обработке записываются в обрамлении <? и ?>.

Секция CDATA используется для того, чтобы обозначить части документа, которые не должны восприниматься как разметка. Секция CDATA начинается со строки <![CDATA[ и заканчивается строкой ]]>. Внутри самой секции не должна присутствовать строка ]]>:

<example>

<![CDATA[ <aaa>bb&cc<<<]]>

</example>

Если XML-документ оформлен по описанным выше правилам, то он называется правильно построенным документом (well-formed document). Если правильно построенный XML-документ удовлетворяет некой семантической схеме, задающей его структуру и содержание, то он называется действительным документом (valid document).

Приведём XML-документ с описанием планет, который будет использован далее в примерах кода:

<?xml version="1.0" encoding="utf-8" ?>

<!-- первые четыре планеты -->

<planets>

<planet>

<name>Mercury</name>

</planet>

<planet>

<name>Venus</name>

</planet>

<planet>

<name>Earth</name>

<moon>

<name>Moon</name>

<period units="days">27.321582</period>

</moon>

</planet>

<planet>

<name>Mars</name>

<moon>

<name>Phobos</name>

<period units="days">0.318</period>

</moon>

<moon>

<name>Deimos</name>

<period units="days">1.26244</period>

</moon>

</planet>

</planets>

Рис. 5. Древовидная структура XML-данных.

Отметим, что при описании дерева XML-элементов используются следующие термины (см. рис. 5):

1. Текущий элемент (self);

2. Предок (ancestor) – любой элемент, содержащий текущий;

3. Корень (root) – предок всех элементов;

4. Родитель (parent) – непосредственный предок текущего элемента;

5. Потомок (descendant) – любой элемент, вложенный в текущий;

6. Ребёнок (child) – непосредственный потомок текущего элемента;

7. Сиблинги (siblings) – элементы, имеющие общего родителя.

В XML-документе с описанием планет элемент <name> используется и как имя планеты, и как имя луны. Ссылки на <name> будут неоднозначны – два одинаковых имени несут разную смысловую нагрузку. Для устранения неоднозначности и обеспечения семантической уникальность элемента предназначены пространства имён XML.

Чтобы связать элемент с пространством имён, используется специальный атрибут xmlns. Обычно для идентификатора пространства имён используют унифицированный идентификатор ресурса (Uniform Resource Identifier, URI), чтобы уменьшить риск совпадения идентификаторов в разных документах.

<!-- фрагмент документа с планетами -->

<planet>

<name xmlns="http://astronomy.com/planet" >Earth</name>

<moon>

<name xmlns="http://astronomy.com/moon" >Moon</name>

<period units="days">27.321582</period>

</moon>

</planet>

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

<!-- пространства имён обычно определяют в начале документа -->

<planets xmlns="http://astronomy.com/planet"

xmlns:m="http://astronomy.com/moon">

<planet>

<name>Earth</name>

<m:moon>

<m:name>Moon</m:name>

<m:period m:units="days">27.321582</m:period>

</m:moon>

</planet>

</planets>