Страницы

Поиск по вопросам

понедельник, 13 апреля 2020 г.

Xml-сериализация атрибутов вложенных узлов в свойства объекта

#c_sharp #xml #net

                    
Подскажите пожалуйста, есть ли возможность десериализовать Xml-элемент подобной структуры:
  
    
    
    
  

в объект примерно такого класса:
[XmlRoot("Service")]
public class Service
{
    public string Host { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
}

То есть смысл в том, чтобы не создавать для каждого вложенного узла свой класс, наподобие
этого:
public class Host
{
    [XmlAttribute("value")]
    public string Value { get; set; }
}

и затем не городить огород:
[XmlRoot("Service")]
public class Service
{
    [XmlElement("Host")]
    public Host Host { get; set; }
    .
    .
    .
}

...

var host = service.Host.Value;

Хочется верить, что атрибуты "value" всех вложенных узлов можно сразу замапить на
string-свойства. Буду благодарен за любой совет.    


Ответы

Ответ 1



Может быть, пусть Service имплементирует интерфейс IXmlSerializable и реализует ReadXml разумным образом? Сделать это только при помощи атрибутов невозможно: свойства определяют либо такой: http://domain.com:80 user_name password либо такой синтаксис. Я тут набросал код: [XmlRoot] class Service : IXmlSerializable { string Host; string Username; string Password; XmlSchema IXmlSerializable.GetSchema() { return null; } void IXmlSerializable.ReadXml(XmlReader reader) { if (reader.IsEmptyElement) // проверяем формат throw new Exception(); // надо какое-то другое исключение, конечно reader.ReadStartElement(); // читаем открывающий тег Service while (reader.IsStartElement()) // пока есть вложенные теги... processNode(reader); // читаем их reader.ReadEndElement(); // читаем закрывающий тег } void processNode(XmlReader reader) { if (!reader.IsEmptyElement) // опять проверяем формат throw new Exception(); if (reader.AttributeCount != 1) // то же самое throw new Exception(); string name = reader.Name; string value = reader.GetAttribute(0); setField(name, value); reader.ReadStartElement(); // переходим к следующему } void setField(string name, string value) { switch (name) // ну или reflection, если хотите { case "Host": Host = value; break; case "Username": Username = value; break; case "Password": Password = value; break; } } void IXmlSerializable.WriteXml(XmlWriter writer) { serializeField(writer, "Host", Host); serializeField(writer, "Username", Username); serializeField(writer, "Password", Password); } void serializeField(XmlWriter writer, string name, string value) { writer.WriteStartElement(name); writer.WriteStartAttribute("Value"); writer.WriteString(value); writer.WriteEndElement(); } }

Комментариев нет:

Отправить комментарий