Думаю, что если вас заинтересовала работа с XmlSerializer, то вы знакомы
с некотороми основами .NET Framework. Поэтому я не буду углубляться в
основы написания программы "Hello! word", а сразу перейду
непосредственно к XmlSerializer. Примеры, представленные здесь, написаны
на языке C#.
Начнем с простого (желающие опустить простое, могут переместиться в
конец статьи и ознакомиться с более сложными вариантами) Вот так будет
выглядеть XML файл, который мы сейчас с вами построим, а потом прочтем
используя XmlSerializer.
<?xml version="1.0" encoding="utf-8" ?>
<Student xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Active="Yes">
<First_Name>Ivan</First_Name>
<Last_Name>Petrov</Last_Name>
</Student>
Посмотрим, как выглядит класс, который описывает структуру нашего XML.
public class Student
{
[XmlAttribute]
public string Active;
[XmlElement(ElementName = "First_Name")]
public string FirstName;
[XmlElement(ElementName = "Last_Name")]
public string LastName;
}
Хорошо, класс у нас есть, выглядит он достаточно просто, теперь надо
посмотреть как же такой класс превращают в XML файл.
public class Run
{
public static void Main()
{
Run test = new Run();
test.CreateDocument("Test.xml");
}
public void CreateDocument(string filename){
// мы создаем обьект типа Student и присваиваем
// некоторые значения полям этого обьекта
Student st= new Student();
st.FirstName="Ivan";
st.LastName="Petrov";
st.Active="Yes";
// Здесь мы создаем обьект класса XmlSerializer,
// который будет работать с обьектами класса Student:
XmlSerializer serializer = new XmlSerializer(typeof(Student));
// Ну и наконец заводим указатель fs на файл, в который хотим писать
TextWriter fs = new StreamWriter(filename);
// и благолополучно сериализуем наш обьект в XML.
serializer.Serialize(fs, st);
fs.Close();
}
}
Теперь мы можем прочесть наш XML файл.
public void ReadDocument(string filename)
{
XmlSerializer serializer = new XmlSerializer(typeof(Student));
FileStream fs = new FileStream(filename, FileMode.Open);
Student st;
st = (Student)serializer.Deserialize(fs);
fs.Close();
Console.Write(st.Active + "\n");
Console.Write(st.FirstName + "\n");
Console.Write(st.LastName + "\n");
}
Ну, тут тоже ничего хитрого нет, создали, как и в предыдущем случае
обьект класса XmlSerializer, который будет работать с обьектами класса
Student Открыли наш XML фаил для чтения. Создали обьект класса Student
десериалезировали туда наш файл и распечатали. Да, не забудьте, что для
работы с XML сериалазером нам потребуется сделать using System.Xml;
using.Xml.Serialization; , а для работы с файлами - using System.IO;
Отлично, мы разобрались как работать с простым XML файлом, теперь
попробуем его усложнить.
<?xml version="1.0" encoding="utf-8" ?>
<Student xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" Active="Yes">
<Student_Name Sex="M">
<First_Name>Ivan</First_Name>
<Last_Name>Petrov</Last_Name>
</Student_Name>
</Student>
Обратите внимание, теперь имя и фамилия у нас не просто так болтаются
не пойми, где, а вложены во внутрь отдельного тага Student_Name.
Посмотрим, как будет выглядеть XML class, описывающий, подобное
вложение.
public class Student
{
[XmlAttribute]
public string Active;
[XmlElement(ElementName = "Student_Name")]
public StudentName Name;
}
public class StudentName
{
[XmlAttribute]
public string Sex;
[XmlElement(ElementName = "First_Name")]
public string FirstName;
[XmlElement(ElementName = "Last_Name")]
public string LastName;
}
Вроде, все не так сложно, наш класс Student содержит в себе обьект
типа StudentName. Ну, а класс StudentName уже содержит в себе Last_Name
и First_Name, а также атрибут Sex, который будет у нас обозначать пол
данного индивидуума. Посмотрим, как получить XML файл из такого класса.
public void CreateDocument(string filename)
{
//Сначала инициализируем обьект внутренего класса.
StudentName name = new StudentName();
name.FirstName="Ivan";
name.LastName="Petrov";
name.Sex="M";
//Затем инициализируем внешний класс.
Student st = new Student();
st.Name=name;
st.Active="Yes";
XmlSerializerserializer=newXmlSerializer(typeof(Student));
TextWriterfs=newStreamWriter(filename);
//и сериализуем наш обьект в XML.
serializer.Serialize(fs, st);
fs.Close();
}
Файл записали. Чтение файла ничем существенно не отличается от
предыдущего примера.
public void ReadDocument(string filename)
{
XmlSerializer serializer = new XmlSerializer(typeof(Student));
FileStream fs = new FileStream(filename, FileMode.Open);
Student st;
st = (Student)serializer.Deserialize(fs);
fs.Close();
Console.Write(st.Active + "\n");
Console.Write(st.Name.Sex + "\n");
Console.Write(st.Name.FirstName + "\n");
Console.Write(st.Name.LastName + "\n");
}
Усложним структуру XML файла еще. Заведем не одного студента, а
список студентов.
<?xml version="1.0" encoding="utf-8" ?>
<Student_List xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<students>
<Student Active="Yes">
<Student_Name Sex="M">
<First_Name>Ivan</First_Name>
<Last_Name>Petrov</Last_Name>
</Student_Name>
</Student>
<Student Active="Yes">
<Student_Name Sex="F">
<First_Name>Anna</First_Name>
<Last_Name>Ivanova</Last_Name>
</Student_Name>
</Student>
</students>
</Student_List>
А вот так будет выглядеть класс, который описывает структуру такого
XML файла.
public class Student_List
{
public Student[] students;
}
public class Student
{
[XmlAttribute]
public string Active;
[XmlElement(ElementName = "Student_Name")]
public StudentName Name;
}
public class StudentName
{
[XmlAttribute]
public string Sex;
[XmlElement(ElementName = "First_Name")]
public string FirstName;
[XmlElement(ElementName = "Last_Name")]
public string LastName
}
Т.е. фактически мы просто дорисовали сверху еще один класс, который
содержит в себе массив обьектов класса Student. Теперь напишем функцию
CreateDocument.
public void CreateDocument(string filename)
{
StudentName Name1 = new StudentName();
Name1.FirstName="Ivan";
Name1.LastName="Petrov";
Name1.Sex="M";
Student St1 = new Student();
St1.Name=Name1;
St1.Active="Yes";
StudentName Name2 = new StudentName();
Name2.FirstName="Anna";
Name2.LastName="Ivanova";
Name2.Sex="F";
Student St2 = new Student();
St2.Name=Name2;
St2.Active="Yes";
Student[] Sts={St1,St2};
Student_List List = new Student_List();
List.students =Sts;
XmlSerializer serializer = new XmlSerializer(typeof(Student_List));
TextWriter fs = new StreamWriter(filename);
serializer.Serialize(fs, List);
fs.Close();
}
Далее напишем функцию для чтения XML файла.
public void ReadDocument(string filename)
{
XmlSerializer serializer = new XmlSerializer(typeof(Student_List));
TextReader fs = new StreamReader(filename);
Student_List List;
List = (Student_List)serializer.Deserialize(fs);
fs.Close();
Student[] Sts = List.students;
foreach (Student St in Sts)
{
Console.Write("next student \n");
Console.Write(St.Active+ "\n");
Console.Write(St.Name.FirstName+ "\n");
Console.Write(St.Name.LastName+ "\n");
Console.Write(St.Name.Sex+ "\n");
}
}
Здесь существенное отличие в том, что поскольку студентов может быть
много, то мы просматриваем данные с помощью foreach.Вобщем-то все.
Осталось, для полноты картины, добавить проверки на неизвестные элементы
и аттрибуты в ReadDocument, чтоб сократить колличество возможных
поломок.
serializer.UnknownNode+= new XmlNodeEventHandler(serializer_UnknownNode);
serializer.UnknownAttribute+= new
XmlAttributeEventHandler(serializer_UnknownAttribute);
Сами же функции serializer_UnknownNode, serializer_UnknownAttribute
будут выглядеть так:
protected void serializer_UnknownNode (object sender, XmlNodeEventArgs e)
{
Console.WriteLine("Unknown Node:" + e.Name + "\t" + e.Text);
}
protected void serializer_UnknownAttribute (object sender, XmlAttributeEventArgs e)
{
System.Xml.XmlAttribute attr = e.Attr;
Console.WriteLine("Unknown attribute " + attr.Name + "=´"
+ attr.Value + "´");
}
Теперь совсем все. Спасибо за внимание.