web-dev-qa-db-ja.com

オブジェクトのリストをシリアル化した後に生成された<ArrayOf> XML属性の名前を変更する方法

オブジェクトのリストList<TestObject>をシリアル化していますが、XmlSerializerが<ArrayOfTestObject>属性を生成します。名前を変更するか、削除します。
リストをフィールドとしてカプセル化した新しいクラスを作成することで実行できますか?

 [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>
27
ilann

最も信頼できる方法は、最も外側のDTOクラスを宣言することです。

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

シリアル化that(つまり、リストを別のオブジェクトに配置します)。


あなたcanラッパークラスを避けますが、私はしません:

_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; }
}
_

problemこれは、カスタム属性を使用する場合、veryシリアライザーの保存と再利用に注意する必要があることです。そうしないと、lotsになります。 =メモリにロードされた動的アセンブリの数。 XmlSerializer(Type)コンストラクターを使用する場合は、これが内部的に自動的にキャッシュされるため、これは回避されます。

29
Marc Gravell

次の行を次のように変更します。

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

に:

XmlRootAttribute root = new XmlRootAttribute("TestObjects");     

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

動作するはずです。

6
Sue Hu

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

次のような別のクラスを作成します。

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

       }

次に、封印しながら以下のコードを適用します。

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