如何重命名序列化对象列表后生成的<ArrayOf> XML属性

ila*_*ann 27 c# xml xml-serialization

我正在序列化对象列表 List<TestObject> ,XmlSerializer生成<ArrayOfTestObject>属性,我想重命名或删除它.
可以通过创建将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>
Run Code Online (Sandbox Code Playgroud)

Mar*_*ell 29

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

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

并序列化(即将您的列表放入另一个对象).


避免包装类,但我不会:

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Fedearne哪个更好/更简单的方法是什么?你的意思是接受的答案与上面的第二个建议*相同*?并且非常仔细地注意我为什么这是危险的原因. (2认同)

小智 6

更改以下行:

XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>));
Run Code Online (Sandbox Code Playgroud)

至:

XmlRootAttribute root = new XmlRootAttribute("TestObjects");     

XmlSerializer serializer = new XmlSerializer(typeof(List<TestObject>), root);
Run Code Online (Sandbox Code Playgroud)

它应该工作.


Jso*_*ham 5

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

XmlSerializer xsSubmit = new XmlSerializer(typeof(List<DropDownOption>), new XmlRootAttribute("DropDownOptions"));
Run Code Online (Sandbox Code Playgroud)

这将导致以下结构:

<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>
Run Code Online (Sandbox Code Playgroud)