将键值对XML反序列化为Class对象

时间:2015-05-21 08:20:02

标签: c# asp.net xml deserialization xml-deserialization

我的XML具有键值对,如下所述:

<Employee>
    <item>
        <key>Name</key>
        <value>XYZ</value>
    </item>
    <item>
        <key>Phone</key>
        <value>1234567890</value>
    </item>
    <item>
        <key>Date of Birth</key>
        <value>19-06-1984</value>
    </item>
    <item>
        <key>Employee ID</key>
        <value>1</value>
    </item>
</Employee>

我有如下所述的Property类:

public class Employee
{
    public string Name { get; set; }

    public string Phone { get; set; }

    public DateTime? DOB { get; set; }

    public int? Id { get; set; }
}

我需要将此XML反序列化为属性类,但我不明白实现此目的的正确方法。

我可以使用Reflection来实现它但我听说Reflection会降低性能,所以想知道有没有更好的方法来实现这一目标?

4 个答案:

答案 0 :(得分:0)

这应该做到

List<Employee> employees = new List<Employee>();
XElement xElement = XElement.Load("Employees.xml");
IEnumerable<XElement> xmlEmployees = xElement.Elements("Employee");
foreach (var xmlEmployee in xmlEmployees)
{
    Employee employee = new Employee();
    foreach (var item in xmlEmployee.Elements("item"))
    {
        string key = item.Element("key").Value;
        string value = item.Element("value").Value;
        switch (key)
        {
            case "Name":
                employee.Name = value;
                break;
            ...
        }
    }
    employees.Add(employee);
}

答案 1 :(得分:0)

像这样实施IXmlSerializable

public class Employee : IXmlSerializable
{
    public string Name { get; set; }

    public string Phone { get; set; }

    public DateTime? DOB { get; set; }

    public int? Id { get; set; }

    public System.Xml.Schema.XmlSchema GetSchema()
    {
        return null;
    }

    public void ReadXml(XmlReader reader)
    {
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    if (string.Equals(reader.Name, "item", StringComparison.InvariantCultureIgnoreCase))
                    {
                        // move to 'key'
                        reader.Read();
                        if (reader.Name != "key") throw new SerializationException();
                        string key = reader.ReadElementContentAsString();
                        if (reader.Name != "value") throw new SerializationException();
                        switch (key)
                        {
                            case "Name":
                                this.Name = reader.ReadElementContentAsString();
                                break;
                            case "Phone":
                                this.Phone = reader.ReadElementContentAsString();
                                break;
                            case "Date of Birth":
                                this.DOB = DateTime.Parse(reader.ReadElementContentAsString());
                                break;
                            case "Employee ID":
                                this.Id = reader.ReadElementContentAsInt();
                                break;
                        }
                    }
                    else
                    {
                        // something was wrong
                        throw new SerializationException();
                    }
                    break;
                case XmlNodeType.EndElement:
                    reader.Read();
                    return;
            }
        }
    }

    public void WriteXml(XmlWriter writer)
    {
        throw new NotImplementedException();
    }
}

并使用标准XmlSerializer

XmlSerializer ser = new XmlSerializer(typeof(Employee));
using (var stream = File.OpenRead(@"D:\Temp\employee.xml"))
{
    var item = ser.Deserialize(stream);
}

答案 2 :(得分:0)

        var serializer = new XmlSerializer(typeof(Employee));
        using (var reader = new StringReader("Your xml"))
        {
            var _emp = (Employee)serializer.Deserialize(reader);

            var _emp2 = new Employee2()
            {
                DOB = _emp.Items.Where(x => x.key == "Date of Birth").Select(x => Convert.ToDateTime(x.value)).First(),
                Name = _emp.Items.Where(x => x.key == "Name").Select(x => x.value).First(),
                Phone = _emp.Items.Where(x => x.key == "Phone").Select(x => x.value).First(),
                Id = _emp.Items.Where(x => x.key == "Employee ID").Select(x => Convert.ToInt32(x.value)).First()

            };

        }

desirialization类

[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
[System.Xml.Serialization.XmlRootAttribute(Namespace = "", IsNullable = false)]
public partial class Employee
{

    private EmployeeItem[] itemsField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute("item", Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public EmployeeItem[] Items
    {
        get
        {
            return this.itemsField;
        }
        set
        {
            this.itemsField = value;
        }
    }
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.0.30319.1")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType = true)]
public partial class EmployeeItem
{

    private string keyField;

    private string valueField;

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string key
    {
        get
        {
            return this.keyField;
        }
        set
        {
            this.keyField = value;
        }
    }

    /// <remarks/>
    [System.Xml.Serialization.XmlElementAttribute(Form = System.Xml.Schema.XmlSchemaForm.Unqualified)]
    public string value
    {
        get
        {
            return this.valueField;
        }
        set
        {
            this.valueField = value;
        }
    }
}

我不喜欢这个解决方案,因为复杂性应该更多。 如果我遇到这个任务,我会使用automapper。但我不记得它的正确语法。

答案 3 :(得分:0)

CREATE DEFINER = CURRENT_USER TRIGGER `MyDatabase`.`TableName_BEFORE_INSERT`
BEFORE INSERT ON `TableName` FOR EACH ROW
BEGIN
IF (NEW.column1,column2 REGEXP '^[augc]+' ) = 0 THEN 
ROLLBACK;
SIGNAL SQLSTATE '12345'
SET MESSAGE_TEXT = 'Your Input can contain only the following letters 'AUGC'. Please correct your input format;
END IF;
END
DELIMITER;