Назовите каждый элемент в массиве - PullRequest
1 голос
/ 06 марта 2012

У меня есть массив, индексы которого соответствуют значениям Enum.Я хотел бы использовать библиотеки C # Xml Serialization для сериализации этого массива.Однако я хотел бы, чтобы каждый узел Xml произносил имя представляемого им типа Enum.Как я могу это сделать?

Пример:

public class NumberOfEmployees
{
   public enum EmployeeType { Lawyer, Doctor, Engineer };

   public int[] NumEmployees { get; set; }

   // Constructor initializes array to size of "EmployeeType"
   public NumberOfEmployees()
   {
      int size = Enum.GetValues(typeof(EmployeeType)).Length;
      this.NumEmployees = new int[size];
   }    
}


Main()
{
   NumberOfEmployees numEmployees = new NumberOfEmployees();
   // Add doctors, lawyers, engineers, etc...
   // numEmployees.NumEmployees[(int)NumberOfEmployees.Lawyer] = 3;
   // numEmployees.NumEmployees[(int)NumberOfEmployees.Doctor] = 2;
   // numEmployees.NumEmployees[(int)NumberOfEmployees.Engineer] = 1;

   // Serialize to "file"
   FileStream fs = new FileStream(file, FileMode.OpenOrCreate);
   XmlSerializer xml = new XmlSerializer(typeof(NumberOfEmployees));   
   xml.Serialize(fs, numEmployees);
   fs.Close();
}

Конечным результатом является xml, который выглядит примерно так:

<NumEmployees>
  <int>3</int>
  <int>2</int>
  <int>1</int>
</NumEmployees>

Но я хочу:

<NumEmployees>
  <Lawyer>3</Lawyer>
  <Doctor>2</Doctor>
  <Engineer>1</Engineer>
</NumEmployees>

Я не могу хранить каждое число отдельно - это должен быть массив.

Спасибо.

1 Ответ

4 голосов
/ 06 марта 2012

Вы можете реализовать интерфейс IXmlSerializable для полной настройки сериализации с помощью XmlSerializer.Нечто похожее на следующее:

public class NumberOfEmployees : IXmlSerializable
{
    public int[] NumEmployees { get; set; }

    // Constructor initializes array to size of "EmployeeType"
    public NumberOfEmployees()
    {
        int size = Enum.GetValues(typeof(EmployeeType)).Length;
        this.NumEmployees = new int[size];
    }

    public XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        reader.ReadStartElement();
        NumEmployees[(int)EmployeeType.Lawyer] = int.Parse(reader.ReadElementString("Lawyer"));
        NumEmployees[(int)EmployeeType.Doctor] = int.Parse(reader.ReadElementString("Doctor"));
        NumEmployees[(int)EmployeeType.Engineer] = int.Parse(reader.ReadElementString("Engineer"));
        reader.ReadEndElement();
    }

    public void WriteXml(XmlWriter writer)
    {
        writer.WriteElementString("Lawyer", NumEmployees[(int)EmployeeType.Lawyer].ToString());
        writer.WriteElementString("Doctor", NumEmployees[(int)EmployeeType.Doctor].ToString());
        writer.WriteElementString("Engineer", NumEmployees[(int)EmployeeType.Engineer].ToString());
    }
}

После того, как вы сделали все это, может показаться бессмысленным продолжать использовать XmlSerializer, поскольку ваш класс обрабатывает всю работу по сериализации.Однако все еще имеет смысл, если NumberOfEmployees является частью более крупной XML-структуры (что, я полагаю, так и есть).

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

Более подробная информация об интерфейсе IXmlSerializable доступна здесь:

http://msdn.microsoft.com/en-us/library/system.xml.serialization.ixmlserializable.aspx

...