Чтение из XML-файла в класс C# с помощью сериализации

у меня есть следующий XML-файл, который я пытаюсь прочитать в классе на c# с помощью де-сериализации:

<?xml version="1.0"?>
    <PropertiesMapping>
        <Property>
            <WEB_Class>InfoRequest</WEB_Class>
            <COM_Class>CInfoReq</COM_Class>
            <Mappings>
                <Map>
                    <WEB_Property>theId</WEB_Property>
                    <COM_Property>TheID</COM_Property>
                </Map>
                <Map>
                    <WEB_Property>theName</WEB_Property>
                    <COM_Property>NewName</COM_Property>
                </Map>
            </Mappings>
        </Property>
    </PropertiesMapping>

ниже приведен код, который я использую, и пока он выполняется без ошибок, никакие данные не читаются в класс PropertiesMapping, где я ошибаюсь??

PropertiesMapping pm = null;

        try
        {
            System.IO.StreamReader str = new System.IO.StreamReader(@"PropertyMapping.xml");
            System.Xml.Serialization.XmlSerializer xSerializer = new System.Xml.Serialization.XmlSerializer(typeof(PropertiesMapping));
            pm = (PropertiesMapping)xSerializer.Deserialize(str);
            str.Close();
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }


[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true, Namespace = "")]
    [System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
    public class PropertiesMapping
    {
        private string m_WEB_Class = "";
        private string m_COM_Class = "";

        private List<IndividualProperties> m_EachProperty = null;

        public string WEB_Class
        {
            get
            {
                return m_WEB_Class;
            }
            set
            {
                m_WEB_Class = value;
            }
        }

        public string COM_Class
        {
            get
            {
                return m_COM_Class;
            }
            set
            {
                m_COM_Class = value;
            }
        }

        public IndividualProperties GetIndividualProperties(int iIndex)
        {
            return m_EachProperty[iIndex];
        }

        public void SetIndividualProperties(IndividualProperties theProp)
        {
            m_EachProperty.Add(theProp);
        }
    }



public class IndividualProperties
    {
        private string m_WEB_PropertyField;

        private string m_COM_PropertyField;

        public string WEB_Property
        {
            get
            {
                return this.m_WEB_PropertyField;
            }
            set
            {
                this.m_WEB_PropertyField = value;
            }
        }

        public string COM_Property
        {
            get
            {
                return this.m_COM_PropertyField;
            }
            set
            {
                this.m_COM_PropertyField = value;
            }
        }
    }

3 ответов


можно использовать XmlElementAttribute для упрощения именования C#.

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

вам нужно будет использовать XmlArrayItemAttribute на Mappings элемент.

представляет атрибут, указывающий производные типы, которые XmlSerializer может поместить в сериализованный матрица.

классы:

[XmlType("PropertiesMapping")]
public class PropertyMapping
{
    public PropertyMapping()
    {
        Properties = new List<Property>();
    }

    [XmlElement("Property")]
    public List<Property> Properties { get; set; }
}

public class Property
{
    public Property()
    {
        Mappings = new List<Mapping>();
    }

    [XmlElement("WEB_Class")]
    public string WebClass { get; set; }

    [XmlElement("COM_Class")]
    public string ComClass { get; set; }

    [XmlArray("Mappings")]
    [XmlArrayItem("Map")]
    public List<Mapping> Mappings { get; set; }
}

[XmlType("Map")]
public class Mapping
{
    [XmlElement("WEB_Property")]
    public string WebProperty { get; set; }

    [XmlElement("COM_Property")]
    public string ComProperty { get; set; }
}

демо:

PropertyMapping result;

var serializer = new XmlSerializer(typeof(PropertyMapping));

using(var stream = new StringReader(data))
using(var reader = XmlReader.Create(stream))
{
    result = (PropertyMapping) serializer.Deserialize(reader);
}

вам не нужно явно объявлять свойства. Просто убедитесь, что имена совпадают. Единственная часть по умолчанию -[XmlArrayItem("Map")] атрибут вам нужно будет использовать другое имя для массива карты.

вы можете, однако, использовать разные имена, как у меня для COM_Property и WEB_Property указать XmlElementAttribute.

class Program
{
    static void Main(string[] args)
    {
        string testData = @"<?xml version=""1.0""?>
<PropertiesMapping>
    <Property>
        <WEB_Class>InfoRequest</WEB_Class>
        <COM_Class>CInfoReq</COM_Class>
        <Mappings>
            <Map>
                <WEB_Property>theId</WEB_Property>
                <COM_Property>TheID</COM_Property>
            </Map>
            <Map>
                <WEB_Property>theName</WEB_Property>
                <COM_Property>NewName</COM_Property>
            </Map>
        </Mappings>
    </Property>
</PropertiesMapping>";

        var sr = new System.IO.StringReader(testData);
        var xs = new XmlSerializer(typeof(PropertiesMapping));

        object result = xs.Deserialize(sr);
    }
}

[Serializable]
public class PropertiesMapping
{
    public Property Property { get; set; }
}

[Serializable]
public class Property
{
    [XmlElement("WEB_Class")]
    public string WebClass { get; set; }

    [XmlElement("COM_Class")]
    public string ComClass { get; set; }

    [XmlArrayItem("Map")]
    public Mapping[] Mappings { get; set; }
}

[Serializable]
public class Mapping
{
    [XmlElement("WEB_Property")]
    public string WebProperty { get; set; }

    [XmlElement("COM_Property")]
    public string ComProperty { get; set; }
}

в зависимости от того, что вы пытаетесь достичь, это может быть сделано легче с XDocument и Linq-to-XML.

что касается сериализации, вот структура класса для вас:

public class PropertiesMapping{
  [XmleElement]
  public string WEB_Class {get;set;}
  [XmleElement]
  public string COM_Class{get;set;}

  [XmlArray("Mappings")]
  public Map[] Mappings {get;set;}
}

public class Map{
  [XmleElement]
  public string WEB_Property{get;set;}
  [XmleElement]
  public string COM_Property{get;set;}
}