2009-10-01 2 views
1

У меня есть следующий формат XML:Как создать класс XML Serializer

<FavouriteSettings xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Customer> 
    <ID>12</ID> 
    <ID>2</ID> 
    <ID>5</ID> 
    </Customer> 

    <Supplier> 
    <ID>158</ID> 
    <ID>23</ID> 
    <ID>598</ID> 
    </Supplier> 
</FavouriteSettings> 

========================= ====================================
у меня будет класс как ниже

class FavouriteList 
{ 
    public string Name; // this name will be "Customer" and "Supplier" 
    public List<int> aList; // to store those "ID" value 
} 

Class FavouriteSettings 
{ 
    public List<FavouriteList> bigList; 
} 

Что мне нужно сделать или изменить, чтобы этот класс работал с XMLSerializer, чтобы сгенерировать XML-файл, подобный этому формату, и десериализоваться обратно в список и класс как FavouriteList?

+0

(добавлен второй пример, показывающий, LINQ к XML с существующими типами) –

ответ

0

XMLSerializer (обычный), как делать свою собственную вещь, и результат часто довольно уродлив. Вы можете полуавтоматизировать сериализацию, реализуя IXmlSerializable, однако, если у вас есть что-то вроде «List», .NET будет ее уничтожать.

Я думаю, вы могли бы получить именно этот результат, используя вместо этого DataContractXmlSerializer. Пометьте класс с помощью [DataContract] и поместите [DataMember] по каждому элементу, который вы хотите сериализовать.

+0

DataContractXmlSerializer? Есть такой зверь? DataContractSerializer, otoh - плохой выбор для конкретного xml; например, очень мало контроля над такими вещами, как атрибуты. Для xml используйте 'XmlSerializer' или напишите его самостоятельно с помощью' XDocument' и т. Д. –

+0

спасибо, но я должен использовать XmlSerializer – 2009-10-06 03:32:21

0

Я считаю, что вы можете использовать атрибуты для управления порядком сериализации данных. См. Статью MSDN: «Attributes That Control XML Serialization».

+0

спасибо за указание ... – 2009-10-06 03:31:12

2

Вы можете использовать следующие классы вместе с XmlSerializer сериализации/десериализации в/из нужного XML:

public class FavouriteSettings 
    { 
    public ID[] Customer 
    { 
     get; 
     set; 
    } 

    public ID[] Supplier 
    { 
     get; 
     set; 
    } 
    } 

    public class ID 
    { 
    [XmlText()] 
    public int Value 
    { 
     get; 
     set; 
    } 
    } 
+0

отлично !! для указания этого ... Я не думал об этом ... – 2009-10-06 03:33:06

3

XmlSerializer разработан, чтобы быть очень прямой перевод ваших объектов в XML; вы может использовать IXmlSerializable, но это редко стоит. Вам лучше создать объекты, которые отражают структуру xml. Или, проще - использовать XSD, чтобы сделать это для вас:

xsd example.xml 
xsd example.xsd /classes 

Или я подозреваю, следующее будет работать (непроверенные):

using System.Collections.Generic; 
using System.Xml.Serialization; 
public class FavoriteSettings 
{ 
    [XmlArray("Customer")] 
    [XmlArrayItem("ID")] 
    public List<int> Customers { get; set; } 

    [XmlArray("Supplier")] 
    [XmlArrayItem("ID")] 
    public List<int> Suppliers { get; set; } 
} 

В частности, если вы хотите, чтобы элемент («Клиент» и т. д.) менялся в зависимости от данных («Имя» и т. д.) - тогда он не будет работать, если вы не используете IXmlSerializable или напишите его сами с помощью XDocument (или аналогичного). Для простых данных, подобных этому, возможно, XDocument является жизнеспособным вариантом? Но тогда вы делаете много дополнительной работы, особенно во время десериализации.


Вот пример использования вашего существующего класса с помощью LINQ к XML:

static class Program 
{ 
    static void Main() { 
     var favs = new FavouriteSettings 
     { 
      bigList = new List<FavouriteList> 
      { 
       new FavouriteList { 
        Name = "Customer", 
        aList = new List<int>{ 
         12,2,5 
        } 
       }, new FavouriteList { 
        Name = "Supplier", 
        aList = new List<int>{ 
         158, 23, 598 
        } 
       } 
      } 
     }; 
     var el = new XElement("FavoriteSettings", 
      from fav in favs.bigList 
      select new XElement(fav.Name, 
       from item in fav.aList 
       select new XElement("ID", item))); 

     string xml = el.ToString(); 
     Console.WriteLine(xml); 

     el = XElement.Parse(xml); 
     favs = new FavouriteSettings 
     { 
      bigList = new List<FavouriteList>(
       from outer in el.Elements() 
       select new FavouriteList 
       { 
        Name = outer.Name.LocalName, 
        aList = new List<int>(
         from id in outer.Elements("ID") 
         select (int)id 
        ) 
       }) 
     }; 
    } 
} 
+0

На самом деле можно взломать XmlSerializer, чтобы сделать это, если вы хотите добавить некоторые публичные элементы, которые есть только для использования XmlSerializer - см. мой ответ. Тем не менее, это все еще некрасиво. –

+0

отличный пример и полные коды тоже ... спасибо MG – 2009-10-06 03:36:23

1

Если необходимо сохранить все существующие имена в определении класса, как есть, и введение иерархии классов для Заказчик и Поставщик не может быть речи, то вам нужно взломать, как это:

public class FavouriteList 
{ 
    [XmlIgnore] 
    public string Name; // this name will be "Customer" and "Supplier" 

    [XmlElement("ID")] 
    public List<int> aList; // to store those "ID" value 
} 

public class FavouriteSettings 
{ 
    [XmlIgnore] 
    public List<FavouriteList> bigList; 

    [XmlElement("Customer")] 
    public FavouriteList[] Customers 
    { 
     get { return bigList.Where(fl => fl.Name == "Customer").ToArray(); } 
     set { bigList.AddRange(value); } 
    } 

    [XmlElement("Supplier")] 
    public FavouriteList[] Suppliers 
    { 
     get { return bigList.Where(fl => fl.Name == "Supplier").ToArray(); } 
     set { bigList.AddRange(value); } 
    } 
} 
+0

Re your comment; Я думаю, это зависит от того, являются ли «Клиент»/«Поставщик» фиксированными или динамическими - то есть на основе данных. –

+0

Вы имеете в виду, является ли список «типов» фиксированным во время компиляции или расширяемым во время выполнения? –

+0

Я думаю, что каждый день я узнаю новые вещи, потому что я просто новый Линк. Спасибо PM – 2009-10-06 03:34:21

Смежные вопросы