【问题标题】:How to rename <ArrayOf> XML attribute that generated after serializing List of objects如何重命名序列化对象列表后生成的 <ArrayOf> XML 属性
【发布时间】:2011-03-08 22:11:53
【问题描述】:

我正在序列化对象列表List&lt;TestObject&gt; , XmlSerializer 生成&lt;ArrayOfTestObject&gt; 属性,我想重命名或删除它。
可以通过创建将 List 封装为字段的新类来完成吗?

 [XmlRoot("Container")]    
 public class TestObject
 {
     public TestObject() { }                         
     public string Str { get; set; }                         
 }

 List<TestObject> tmpList = new List<TestObject>();

 TestObject TestObj = new TestObject();
 TestObj.Str = "Test";

 TestObject TestObj2 = new TestObject();
 TestObj2.Str = "xcvxc";

 tmpList.Add(TestObj);
 tmpList.Add(TestObj2);


 XmlWriterSettings settings = new XmlWriterSettings();
 settings.OmitXmlDeclaration = true;
 settings.Indent = true;
 XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>));

 using (XmlWriter writer = XmlWriter.Create(@"C:\test.xml", settings))
 {              
     XmlSerializerNamespaces namespaces = new XmlSerializerNamespaces();
     namespaces.Add(string.Empty, string.Empty);
     serializer.Serialize(writer, tmpList, namespaces);                            
}


<ArrayOfTestObject>
  <TestObject>
    <Str>Test</Str>
  </TestObject>
  <TestObject>
    <Str>xcvxc</Str>
  </TestObject>
</ArrayOfTestObject>

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    最可靠的方法是声明一个最外层的 DTO 类:

    [XmlRoot("myOuterElement")]
    public class MyOuterMessage {
        [XmlElement("item")]
        public List<TestObject> Items {get;set;}
    }
    

    并序列化那个(即将你的列表放入另一个对象)。


    可以避免使用包装类,但我不会:

    class Program
    {
        static void Main()
        {
            XmlSerializer ser = new XmlSerializer(typeof(List<Foo>),
                 new XmlRootAttribute("Flibble"));
            List<Foo> foos = new List<Foo> {
                new Foo {Bar = "abc"},
                new Foo {Bar = "def"}
            };
            ser.Serialize(Console.Out, foos);
        }
    }
    
    public class Foo
    {
        public string Bar { get; set; }
    }
    

    与此相关的问题是,当您使用自定义属性时,您需要非常小心地存储和重复使用序列化程序,否则您会得到很多 个加载到内存中的动态程序集。如果您只使用 XmlSerializer(Type) 构造函数,则可以避免这种情况,因为它会自动在内部缓存它。

    【讨论】:

    • 马克一针见血。我在stackoverflow.com/questions/3000934/… 做了类似的把戏
    • 那么有没有办法避免使用另一个类?
    • 有更好更简单的方法,就问这个问题:stackoverflow.com/questions/1237683/…
    • @Fedearne 那是哪种更好/更简单的方法?您的意思是与上述第二个建议相同的公认答案吗?并非常仔细地注意我给出的关于为什么这是危险的推理。
    • @Marc Gravell 我是否需要为我正在序列化的每种类型创建一个单独的 MyOuterMessage?
    【解决方案2】:

    更改以下行:

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

    收件人:

    XmlRootAttribute root = new XmlRootAttribute("TestObjects");     
    
    XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>), root);
    

    它应该可以工作。

    【讨论】:

    • 投了反对票。此方法将插入一个根元素,但仍不会删除“ArrayOfTestObject”元素。
    【解决方案3】:

    您可以向XmlSerializer 构造函数添加一个附加参数,以实质上命名根元素。

    XmlSerializer xsSubmit = new XmlSerializer(typeof(List<DropDownOption>), new XmlRootAttribute("DropDownOptions"));
    

    这将导致以下结构:

    <DropDownOptions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
        <DropDownOption>
          <ID>1</ID>
          <Description>foo</Description>
        </DropDownOption>
        <DropDownOption>
          <ID>2</ID>
          <Description>bar</Description>
        </DropDownOption>
    </DropDownOptions>
    

    【讨论】:

      【解决方案4】:

      创建另一个类,如:

             [XmlRoot("TestObjects")]
             public class TestObjects: List<TestObject>
             {
      
             }
      

      然后在密封时应用以下代码:

                  XmlSerializer serializer = new XmlSerializer(typeof(TestObjects));
                  MemoryStream memStream = new MemoryStream();
                  serializer.Serialize(memStream, tmpList);
      

      【讨论】:

      • 这对我没有任何影响。我内置序列化程序只是查看要序列化的对象是否是List 的子对象,以便应用其特殊的命名方案。
      猜你喜欢
      • 1970-01-01
      • 2012-08-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-25
      • 2017-01-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多