【问题标题】:XML Serialization of List<T> - XML RootList<T> 的 XML 序列化 - XML 根
【发布时间】:2010-11-17 06:49:51
【问题描述】:

关于 Stackoverflow (.Net 2.0) 的第一个问题:

所以我试图用以下内容返回一个列表的 XML:

public XmlDocument GetEntityXml()
    {        
        StringWriter stringWriter = new StringWriter();
        XmlDocument xmlDoc = new XmlDocument();            

        XmlTextWriter xmlWriter = new XmlTextWriter(stringWriter);

        XmlSerializer serializer = new XmlSerializer(typeof(List<T>));

        List<T> parameters = GetAll();

        serializer.Serialize(xmlWriter, parameters);

        string xmlResult = stringWriter.ToString();

        xmlDoc.LoadXml(xmlResult);

        return xmlDoc;
    }

现在这将用于我已经定义的多个实体。

假设我想获得List&lt;Cat&gt;的XML

XML 类似于:

<ArrayOfCat>
  <Cat>
    <Name>Tom</Name>
    <Age>2</Age>
  </Cat>
  <Cat>
    <Name>Bob</Name>
    <Age>3</Age>
  </Cat>
</ArrayOfCat>

有没有办法让我在获取这些实体时始终获取相同的 Root?

例子:

<Entity>
  <Cat>
    <Name>Tom</Name>
    <Age>2</Age>
  </Cat>
  <Cat>
    <Name>Bob</Name>
    <Age>3</Age>
  </Cat>
</Entity>

另外请注意,我不打算将 XML 反序列化回 List&lt;Cat&gt;

【问题讨论】:

  • “始终获取相同的 Root”是什么意思?请提供更多详细信息...

标签: c# xml xml-serialization root generic-list


【解决方案1】:

有一个非常简单的方法:

public XmlDocument GetEntityXml<T>()
{
    XmlDocument xmlDoc = new XmlDocument();
    XPathNavigator nav = xmlDoc.CreateNavigator();
    using (XmlWriter writer = nav.AppendChild())
    {
        XmlSerializer ser = new XmlSerializer(typeof(List<T>), new XmlRootAttribute("TheRootElementName"));
        ser.Serialize(writer, parameters);
    }
    return xmlDoc;
}

【讨论】:

【解决方案2】:

这么简单……

public static XElement ToXML<T>(this IList<T> lstToConvert, Func<T, bool> filter, string rootName)
{
    var lstConvert = (filter == null) ? lstToConvert : lstToConvert.Where(filter);
    return new XElement(rootName,
       (from node in lstConvert
       select new XElement(typeof(T).ToString(),
       from subnode in node.GetType().GetProperties()
       select new XElement(subnode.Name, subnode.GetValue(node, null)))));

}

【讨论】:

    【解决方案3】:

    同一件事的更好方法:

    public XmlDocument GetEntityXml<T>()
    {
        XmlAttributeOverrides overrides = new XmlAttributeOverrides();
        XmlAttributes attr = new XmlAttributes();
        attr.XmlRoot = new XmlRootAttribute("TheRootElementName");
        overrides.Add(typeof(List<T>), attr);
    
        XmlDocument xmlDoc = new XmlDocument();
        XPathNavigator nav = xmlDoc.CreateNavigator();
        using (XmlWriter writer = nav.AppendChild())
        {
            XmlSerializer ser = new XmlSerializer(typeof(List<T>), overrides);
            List<T> parameters = GetAll<T>();
            ser.Serialize(writer, parameters);
        }
        return xmlDoc;
    }
    

    【讨论】:

    • 主要是直接序列化到XmlDocument中。您的代码需要解析结果才能将它们返回到文档中。您的代码还使用了 XmlTextWriter,这在很大程度上已经过时了。
    • 这真的很有帮助,但由于我使用的是无法序列化的字典,所以这篇文章对我帮助很大:theburningmonk.com/2010/05/…
    【解决方案4】:

    如果我理解正确,您希望文档的根始终相同,无论集合中的元素类型如何?在这种情况下,您可以使用 XmlAttributeOverrides :

           XmlAttributeOverrides overrides = new XmlAttributeOverrides();
           XmlAttributes attr = new XmlAttributes();
           attr.XmlRoot = new XmlRootAttribute("TheRootElementName");
           overrides.Add(typeof(List<T>), attr);
           XmlSerializer serializer = new XmlSerializer(typeof(List<T>), overrides);
           List<T> parameters = GetAll();
           serializer.Serialize(xmlWriter, parameters);
    

    【讨论】:

      猜你喜欢
      • 2011-09-28
      • 2013-10-27
      • 2023-03-08
      • 2018-10-30
      • 1970-01-01
      • 1970-01-01
      • 2015-05-30
      • 1970-01-01
      • 2012-04-06
      相关资源
      最近更新 更多