【问题标题】:Deserialize XML to List<>将 XML 反序列化为 List<>
【发布时间】:2018-10-01 21:27:42
【问题描述】:

是否可以将以下 XML 转换为 List?

<?xml version="1.0" encoding="UTF-8"?>
<DATA>
    <SIGNATURES>
        <SIGNATURE>
            <UTILISATEUR>John Doe</UTILISATEUR>
            <ACTEUR>Emetteur</ACTEUR>
            <DATE>20160429</DATE>
        </SIGNATURE>
        <SIGNATURE>
            <UTILISATEUR>Philippe Martin</UTILISATEUR>
            <ACTEUR>Responsable Qualité Projet</ACTEUR>
            <DATE>20160503</DATE>
        </SIGNATURE>
    </SIGNATURES>
</DATA>

我正在寻找以下结果:

但是 XML 是一个例子,我事先不知道结构,所以我无法创建一个具有相同结构的类......我正在寻找一个通用的解决方案。

谢谢。

编辑:

我想描述一个我会适应的简单案例,但事实上,目前我不使用这种 XML 格式。他是这样的:

<DATA>
    <ELEMENTS Cle="NAME_1">
        <ELEMENT>
          <ELEMENT Cle="TAG_1" Valeur="John Doe"></ELEMENT>
          <ELEMENT Cle="TAG_2" Valeur="6 rue du Marché"></ELEMENT>
          <ELEMENT Cle="TAG_3" Valeur="Responsable marketing"></ELEMENT>
          <ELEMENT Cle="TAG_N" Valeur="..."></ELEMENT>
        </ELEMENT>
        <ELEMENT>...</ELEMENT>
    </ELEMENTS>
    <ELEMENTS Cle="NAME_N">...</ELEMENTS>
</DATA>

它“尊重”一种格式,但内容却不尽相同。我将数据提取到一些字典中:

public class Element
{
    public string Valeur { get; set; }
    public Dictionary<string, Dictionary<string, List<Element>>>    taElements  { get; set; }

    public Element()
    {
        taElements  = new Dictionary<string, Dictionary<string, List<Element>>>();
    }

    public void SetXML(string xml)
    {
        var document = XDocument.Parse(xml);
        var root = document.Root;

        foreach (var elements in root.Elements("ELEMENTS"))
        {
            var _taElement = new Dictionary<string, List<Element>>();

            foreach (var element in elements.Descendants("ELEMENT"))
            {
                if (element.Attribute("Cle") == null) { continue; }

                if (!_taElement.ContainsKey(element.Attribute("Cle").Value)) { _taElement.Add(element.Attribute("Cle").Value, new List<Element>()); }

                var elem = new Element();

                if (element.Attribute("Valeur") != null) { elem.Valeur = element.Attribute("Valeur").Value; }

                _taElement[element.Attribute("Cle").Value].Add(elem);

                if (!taElements.ContainsKey(elements.Attribute("Cle").Value)) { taElements.Add(elements.Attribute("Cle").Value, new Dictionary<string, List<Element>>()); }

                taElements[elements.Attribute("Cle").Value] = _taElement;
            }
        }
    }
}

但不可能在 ItemsControl 中绑定字典(这是我的最终目标)。

【问题讨论】:

  • List 在您的通用解决方案中包含什么类型?
  • 仅限@NetMage 字符串
  • 您好,我已经从您的标题中删除了多余的标签,还删除了WPF 标签(您可能正在使用 WPF,但这个问题与 WPF 无关)。
  • 问题没有意义。反序列化某些东西意味着获取它的字符串/二进制表示并将其变成一个对象,以便您可以访问它的属性。如果你不知道类型,你就不能真正做到——即使你可以即时编译一个对象,它也是没用的,因为你的其他代码都不知道如何使用它(类型不知道) t 在编译代码时存在)。如果您只想遍历 XML 中的字符串值,请使用 LINQ to XML

标签: c# xml list linq


【解决方案1】:

查看 XMLSerializer/Deserialize 以获取文档。它将一个类序列化为 XML,或者将一个 XML 流读入一个类。 XML Serialization

    static void Main(string[] args)
    {
        DATA data = new DATA();
        data.SIGNATURES = new List<SIGNATURE>();
        data.SIGNATURES.Add(new SIGNATURE() { ACTEUR = "", DATE= "", UTILISATEUR= "" });
        data.SIGNATURES.Add(new SIGNATURE() { ACTEUR = "", DATE = "", UTILISATEUR = "" });

        XmlSerializer serializer = new XmlSerializer(typeof(DATA));
        using (TextWriter writer = new StreamWriter(@"Xml.xml"))
        {
            serializer.Serialize(writer, data);
        }

        XmlSerializer deserializer = new XmlSerializer(typeof(DATA));
        TextReader reader = new StreamReader(@"myXml.xml");
        object obj = deserializer.Deserialize(reader);
        DATA XmlData = (DATA)obj;
        reader.Close();
    }


  public class SIGNATURE
    {
        public string UTILISATEUR { get; set; }
        public string ACTEUR { get; set; }
        public string DATE { get; set; }
    }

    public class DATA
    {
        public List<SIGNATURE> SIGNATURES { get; set; }
    }

【讨论】:

  • 感谢您的帮助,但我事先不知道 XML 的结构。所以我不能有一个 SIGNATURE 类。
【解决方案2】:

您可以创建一个List&lt;Dictionary&lt;string,string&gt;&gt;,它将使用 LINQ to XML 处理大多数 XML。您可以提取元素的名称。

var xd = XDocument.Parse(doc);
var elementName = xd.FirstChild().Name.ToString().TrimEnd('S');
var ans = xd.Descendants(elementName).Select(d => d.Descendants().ToDictionary(dd => dd.Name.ToString(), dd => dd.Value)).ToList();

如果您需要将ans 绑定到DataGridView,则可以使用DataTable

使用扩展方法,您可以将List&lt;Dictionary&gt; 转换为DataTable

public static DataTable ToDataTable(this IEnumerable<IDictionary<string, string>> rows) {
    var dt = new DataTable();
    if (rows.Any()) {
        foreach (var kv in rows.First())
            dt.Columns.Add(kv.Key, typeof(String));

        foreach (var r in rows)
            dt.Rows.Add(r.Values.ToArray());
    }
    return dt;
}

现在您可以为DataSource 创建一个DataTable

var dt = ans.ToDataTable();

【讨论】:

  • XML 文件总是有一个“ELEMENTS”标签,然后是“ELEMENT”节点,然后是我不知道名字的子节点。但即使使用 ToList () 它仍然是一个字典,因此无法绑定到数据网格?
  • @WDKyle 我不记得这是您原始帖子的要求,但我添加了我将如何处理它。
  • 我还修改了代码以处理任何通用的“ELEMENTS”/“ELEMENT”标签。
猜你喜欢
  • 2011-09-28
  • 2021-11-12
  • 2018-10-30
  • 2011-08-12
  • 2012-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-11
相关资源
最近更新 更多