Inventory inv=new Inventory();
inv.InventoryItems=addProd;
TextWriter tr=new StreamWriter('..\..\..\inventory.xml');
XmlSerializer sr=new XmlSerializer(typeof(Inventory), attrOver);
sr.Serialize(tr, inv);
tr.Close();
}
private void button2_Click(object sender, System.EventArgs e) {
//необходимо выполнить тот же процесс для десериализации
// создаем новую коллекцию XmlAttributes
XmlAttributes attrs=new XmlAttributes();
// добавляем информацию о типе к коллекции элементов
attrs.XmlElements.Add(new XmlElementAttribute('Book', typeof(BookProduct)));
attrs.XmlElements.Add(new XmlElementAttribute('Product', typeof(Product)));
XmlAttributeOverrides attrOver=new XmlAttributeOverrides();
//добавляем к коллекции Attributes (атрибутов)
attrOver.Add(typeof(Inventory), 'InventoryItems', attrs);
//нужен новый объект Inventory для десериализаций в него
Inventory newInv;
// десериализуем и загружаем данные в окно списка из
// десериализованного объекта
FileStream f=new FileStream('..\..\..\inventory.xml', FileMode.Open);
XmlSerializer newSr=new XmlSerializer(typeof(Inventory).attrOver);
newInv=(Inventory)newSr.Deserialize(f);
if (newInv!=null) {
foreach(Product prod in newInv.InventoryItems) listBox1.Items.Add (prod.ProductName);
}
f.Close();
}
// это те же классы, что и в предыдущем примере
// за исключением удаленных атрибутов
// из свойства InventoryItems для Inventory
public class Inventory {
private Product[] stuff;
public Inventory() {}
public Product[] InventoryItems {
get {return stuff;}
set {stuff=value;}
}
}
public class Product {
private int prodId;
private string prodName;
private int suppId;
public Product() {}
public int ProductID {
get {return prodId;}
set {prodId=value;}
}
public string ProductName {
get {return prodName;}
set {prodName=value;}
}
public int SupplierID {
get {return suppId;}
set {suppId=value;}
}
}
public class BookProduct:Product {
private string isbnNum;
public BookProduct() {}
public string ISBN {
get {return isbnNum;}
set {isbnNum=value;}
}
}
Это тот же пример, что и раньше, но первое, что необходимо заметить,— здесь нет добавленных в класс Inventory
атрибутов. Поэтому в данном случае представьте, что классы Inventory
, Product
и производный класс BookProduct
находятся в отдельной DLL, и у нас нет исходного кода.
Первым шагом в процессе является создание объекта на основе XmlAttributes
, и объекта XmlElementAttribute
для каждого типа данных, который будет переопределяться:
XmlAttributes attrs=new XmlAttributes();
attrs.XmlElements.Add(new XmlElementAttribute('Book', typeof(BookProduct)));
attrs.XmlElements.Add(new XmlElementAttribute('Product', typeof(Product)));
Здесь мы добавляем новый XmlElementAttribute
к коллекции XmlElements
класса XmlAttributes
. Класс XmlAttributes
имеет свойства, соответствующие атрибутам, которые могут применяться; XmlArray
и XmlArrayItems
, которые мы видели в предыдущем примере, являются только парой. Теперь мы имеем объект XmlAttributes
с двумя объектами на основе XmlElementAttribute
, добавленными к коллекции XmlElements
. Далее создадим объект XmlAttributeOverrides
:
XmlAttributeOverrides attrOver = new XmlAttributeOverride();
attrOver.Add(typeof(Inventory) , 'Inventory Items', attrs);
Meтод Add
имеет две перегружаемые версии. Первая получает информацию о типе переопределяемого объекта и объект XmlAttributes
, который был создан ранее. Вторая версия та, что мы используем, получает также с строковое значение, которое является членом в переопределенном объекте. В нашем случае мы хотим переопределить член InventoryItems
в классе Inventory
.
Теперь создадим объект XmlSerializer
, добавляя объект XmlAttributeOverrides
в качестве параметра. XmlSerializer
уже знает, какие типы мы хотим переопределить и что нам нужно вернуть для этих типов. Если выполнить метод Serialize
, то получится следующий вывод XML: