XML使用相同的元素名称和不同的属性名称反序列化

时间:2017-04-07 07:48:37

标签: c# xml linq xml-serialization

我想在C#

中对XML进行deseralize
<Test>
<Testdata>
<abc name = "fname"> Test</abc>
<abc name = "lname"> Name</abc
</Testdata>
</Test>

我有一个小例子,我有更大的XML需要解析为.Net对象!!下面是我的对象

Public class Employee
{
      Public string LastName {get; set;}
      Public string FirstName {get;set;}
}

如何使用linq或XML序列化程序对此类xml进行解除分类。

目前我正在使用xdocument,获取名称为abc的所有节点,并使用if else梯形图构建对象,但这不是正确的方法。

测试是名字 名称是XML中的姓氏..

任何帮助都将不胜感激!!

3 个答案:

答案 0 :(得分:0)

您描述的映射不是XmlSerializer支持的映射。如果没有以下方法之一,您无法以这种方式序列化Employee

  • 实施IXmlSerializable - 我推荐;很容易搞砸这个,特别是反序列化代码
  • 通过XDocumentXmlDocument手动完成(再次,相当多的工作)
  • 创建可从XmlSerializer使用的与您的架构匹配的DTO模型

坦率地说,我会使用最后一个选项,这可能意味着创建类似的东西(完全未经测试,但我会在一分钟内尝试):

[XmlRoot("Test")]
public class DtoRoot {
    [XmlArray("Testdata")]
    [XmlArrayItem("abc")]
    public List<KeyValuePair> Items {get;} = new List<KeyValuePair>();

    public string this[string key] => Items.FirstOrDefault(x => x.Key == key)?.Value;
}
public class KeyValuePair{
    [XmlAttribute("name")]
    public string Key {get;set;}
    [XmlText]
    public string Value {get;set;}
}

并使用类似的东西:

Employee emp = new Employee
{
    FirstName = "Fred",
    LastName = "Flintstone"
};
var obj = new DtoRoot {
    Items = {
    new KeyValuePair { Key = "fname", Value = emp.FirstName },
    new KeyValuePair { Key = "lname", Value = emp.LastName},
} };
var ser = new XmlSerializer(typeof(DtoRoot));
ser.Serialize(Console.Out, obj);

给了我们(忽略encoding - 因为Console.Out):

<?xml version="1.0" encoding="ibm850"?>
<Test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Testdata>
    <abc name="fname">Fred</abc>
    <abc name="lname">Flintstone</abc>
  </Testdata>
</Test>

要反序列化:反序列化为DtoRoot实例,然后使用索引器:

var obj = (DtoRoot)ser.Deserialize(source);
var emp = new Employee {
    FirstName = obj["fname"],
    LastName = obj["lname"],
};

答案 1 :(得分:0)

使用xdocument而不是序列化将xml解析为类没有任何问题。这是一种不使用else梯形图的方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;


namespace ConsoleApplication49
{   
    class Program
    {
        const string FILENAME = @"c:\temp\test.xml";
        static void Main(string[] args)
        {
            XDocument doc = XDocument.Load(FILENAME);

            Employee.employees = doc.Descendants("Testdata").Select(x => new Employee()
            {
                FirstName = x.Elements().Where(y => (string)y.Attribute("name") == "fname").Select(y => (string)y).FirstOrDefault(),
                LastName = x.Elements().Where(y => (string)y.Attribute("name") == "lname").Select(y => (string)y).FirstOrDefault()
            }).ToList();

        }
    }
    public class Employee
    {
        public static List<Employee> employees = new List<Employee>();

        public string LastName {get; set;}
        public string FirstName {get;set;}
    }


}

答案 2 :(得分:0)

在此处使用列表。

public class Employee
{
    public static List<Employee> employees = new List<Employee>();

    public Listc<string> Name {get; set;}
}