Исходники.Ру - Программирование
Исходники
Статьи
Книги и учебники
Скрипты
Новости RSS
Магазин программиста

Главная » Статьи по программированию » .NET - Все статьи »

Обсудить на форуме Обсудить на форуме

XmlSerializer - и как с ним бороться
Думаю, что если вас заинтересовала работа с XmlSerializer, то вы знакомы с некотороми основами .NET Framework. Поэтому я не буду углубляться в основы написания программы "Hello! word", а сразу перейду непосредственно к XmlSerializer. Примеры, представленные здесь, написаны на языке C#.
Думаю, что если вас заинтересовала работа с 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 + "´");
}

Теперь совсем все. Спасибо за внимание.


Может пригодится:


Автор: Krassilchik Lucy
Прочитано: 5799
Рейтинг:
Оценить: 1 2 3 4 5

Комментарии: (0)

Добавить комментарий
Ваше имя*:
Ваш email:
URL Вашего сайта:
Ваш комментарий*:
Код безопастности*:

Рассылка новостей
Рейтинги
© 2007, Программирование Исходники.Ру