C# 如何重命名<;阵列式>;序列化对象列表后生成的XML属性

C# 如何重命名<;阵列式>;序列化对象列表后生成的XML属性,c#,xml,xml-serialization,C#,Xml,Xml Serialization,我正在序列化对象列表List ,XmlSerializer生成属性,我想重命名或删除它。 可以通过创建将列表封装为字段的新类来完成吗 [XmlRoot("Container")] public class TestObject { public TestObject() { } public string Str { get; set; } } List&l

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

 [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>
[XmlRoot(“容器”)]
公共类测试对象
{
公共TestObject(){}
公共字符串Str{get;set;}
}
List tmpList=新列表();
TestObject TestObj=新的TestObject();
TestObj.Str=“Test”;
TestObject TestObj2=新的TestObject();
TestObj2.Str=“xcvxc”;
tmpList.Add(TestObj);
tmpList.Add(TestObj2);
XmlWriterSettings=新的XmlWriterSettings();
settings.OmitXmlDeclaration=true;
settings.Indent=true;
XmlSerializer serializer=新的XmlSerializer(typeof(List));
使用(XmlWriter=XmlWriter.Create(@“C:\test.xml”,设置))
{              
XmlSerializerNamespaces=新的XmlSerializerNamespaces();
添加(string.Empty,string.Empty);
serializer.Serialize(writer、tmpList、名称空间);
}
试验
xcvxc

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

[XmlRoot("myOuterElement")]
public class MyOuterMessage {
    [XmlElement("item")]
    public List<TestObject> Items {get;set;}
}
[XmlRoot(“myOuterElement”)]
公共类消息{
[XmlElement(“项目”)]
公共列表项{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; }
}
类程序
{
静态void Main()
{
XmlSerializer ser=新的XmlSerializer(typeof(List),
新的XmlRootAttribute(“Flibble”);
List foos=新列表{
新Foo{Bar=“abc”},
新Foo{Bar=“def”}
};
序列化(Console.Out,foos);
}
}
公开课Foo
{
公共字符串条{get;set;}
}

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

创建另一个类,如:

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

       }

将以下行更改为:

XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>));
XmlSerializer serializer=新的XmlSerializer(typeof(List));
致:

XmlRootAttribute root=新的XmlRootAttribute(“TestObjects”);
XmlSerializer serializer=新的XmlSerializer(typeof(List),root);

它应该可以工作。

您可以向
XmlSerializer
构造函数添加一个附加参数,以基本命名根元素

XmlSerializer xsSubmit = new XmlSerializer(typeof(List<DropDownOption>), new XmlRootAttribute("DropDownOptions"));
XmlSerializer xsSubmit=newxmlserializer(typeof(List),newxmlrootattribute(“dropdownpoptions”);
这将导致以下结构:

<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>

1.
福
2.
酒吧

Marc一针见血。我在上一节课时也玩了类似的把戏,所以没有办法避免使用另一节课?有一个更好更简单的方法,只需回答这个问题:@federane哪个更好/更简单?你指的是与上述第二条建议相同的公认答案吗?并且非常仔细地注意我给出的关于为什么这是危险的推理。@Marc Gravell我需要为我序列化的每种类型创建单独的消息吗?这对我的情况没有任何影响。我猜内置序列化程序只是查看要序列化的对象是否是
List
的子对象,以便应用其特殊的命名方案。
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>