使用序列化将XML文件读入C#类

9
我有以下XML文件,正在尝试使用DE序列化将其读入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;
            }
        }
    }

XML节点名称应与同一结构中的类名称相同。了解类在XML中的样子的一个好方法是通过序列化它:https://dev59.com/4HE95IYBdhLWcg3wft1w - Dr Rob Lang
3个回答

17

您可以使用XmlElementAttribute来简化C#中的命名。

指示公共字段或属性在XmlSerializer序列化或反序列化包含它的对象时表示XML元素。

对于Mappings元素,您需要使用XmlArrayItemAttribute

表示一个属性,用于指定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);
}

2

您不需要显式声明属性。只需确保名称匹配即可。唯一的非默认部分是您需要使用不同名称的[XmlArrayItem("Map")]属性。

但是,您可以使用不同的名称,例如我为COM_PropertyWEB_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; }
}

谢谢。我更喜欢Romoku的解决方案,因为它使用了List<>类型。 - KF-SoftwareDev

0

根据您想要实现的目标,使用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;}
}

谢谢。我受限于 .Net 2.0,因此可以使用 LINQ。 - KF-SoftwareDev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接