【问题标题】:XML Deserialization with dynamic fields使用动态字段的 XML 反序列化
【发布时间】:2014-09-05 04:42:33
【问题描述】:

假设我有以下 xml:

<rootelement>
    <childone>val1</childone>
    <childtwo>val2</childtwo>
    <childthree>val3</childthree>
</rootelement>

要将它反序列化为一个对象,我通常会有这样的东西:

public class rootelement{
    public string childone,childtwo,childthree;
}

一切正常,但现在我想知道是否可以将子节点名称存储在一个数组或其他东西中,以便我可以更轻松地管理我的字段,并使用这个数组来填充 List 中的键KeyValuePair 例如:

string[] fieldnames={"childone","childtwo","childthree"};
List<KeyValuePair<string, string>> fields=new List<KeyValuePair<string, string>>();
for(int i=0;i<fieldnames.Length;i++){
    fields.Add(new KeyValuePair<string,string>(fieldnames[i],""));
}

最后一步是反序列化以填充值。 它不一定是 ListKeyValuePair,任何我可以应用相同概念的东西都可以。

这样的事情可能吗?如果是这样,请帮我举个例子。

【问题讨论】:

    标签: c# .net xml serialization


    【解决方案1】:

    我最终做了以下事情:

    public class MyXmlRoot{
    
    private string[] allowedTags={"tagA","tagB","tagC"};
    
    [XmlAnyElement]
    public List<XmlElement> children = new List<XmlElement>(); //populated after serialization
    
    public string GetValueByKey(string key){
      return children.Find(k => k.Name == key).InnerText;
    }
    
    public void UseTags(){
        for(int i=0;i<allowedTags.Length;i++){
            Console.WriteLine(allowedTags[i]+" = "+GetValueByKey(allowedTags[i]));
        }
    }
    
    }
    

    【讨论】:

      【解决方案2】:

      如果我的理解是正确的,你需要手动反序列化。 这样做的一种选择是使用 XDocument:

      using System;
      using System.Collections.Generic;
      using System.Reflection;
      using System.Xml.Linq;
      using System.Xml.XPath;
      
      class Program
      {
          class Children
          {
              public string one { get; set; }
              public string two { get; set; }
          }
      
          static void Main(string[] args)
          {
              string xmlstr = @"<?xml version=""1.0"" encoding=""utf-8""?>
      <rootelement>
        <childone>val1</childone>
        <childtwo>val2</childtwo>
        <childthree>val3</childthree>
        <children1>
          <children2>
            <one>val1-1</one>
            <two>val1-2</two>
            <three>val1-3</three>
          </children2>
        </children1>
      </rootelement>";
      
              XDocument xml = XDocument.Parse(xmlstr);
      
              string[] fieldnames = { "childone", "childtwo", "childthree" };
              List<KeyValuePair<string, string>> fields = new List<KeyValuePair<string, string>>();
              foreach (string i in fieldnames)
              {
                  XElement elem = xml.Root.XPathSelectElement(i);
                  if (elem != null)
                  {
                      fields.Add(new KeyValuePair<string, string>(i, elem.Value));
                  }
              }
      
              // Debug
              foreach (KeyValuePair<string, string> f in fields)
              {
                  Console.WriteLine(f);
              }
      
              // Try to fill specific object's properties with using reflection
      
              string parentPath = "children1/children2";
              string[] names = { "one", "two", "three" };
              Children childrenFields = new Children();
              foreach (var name in names)
              {
                  PropertyInfo prop = typeof(Children).GetProperty(name);
                  if (prop != null)
                  {
                      XElement elem = xml.Root.XPathSelectElement(parentPath + "/" + name);
                      if (elem != null)
                      {
                          prop.SetValue(childrenFields, elem.Value, null);
                      }
                  }
              }
      
              // Debug
              Console.WriteLine("Children one: {0}, two: {1}",
                  childrenFields.one, childrenFields.two);
          }
      }
      

      此代码使用System.Xml.XPath.Extensions.XPathSelectElement 扩展方法通过XPath 查找目标XML 元素,以支持更复杂的XML 文档,例如我的示例中的children1 元素。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-29
        • 1970-01-01
        • 2012-11-22
        • 1970-01-01
        相关资源
        最近更新 更多