如何在c#中序列化xml对象时定义数组元素的顺序

时间:2014-09-10 18:48:37

标签: c#-4.0 xml-serialization

我有以下课程。

[XmlRoot("MyRoot")]
public class MyRoot
{
    [XmlElement("Node1")]
    public Node1[] Node1 { get; set; }
    [XmlElement("Node2")]
    public Node2[] Node2 { get; set; }
    [XmlElement("Node3")]
    public Node3[] Node3 { get; set; }

}

public class Node1
{
    [XmlElement("Attrib11")]
    public string Attrib11 { get; set; }
    [XmlElement("Attrib12")]
    public string Attrib12 { get; set; }
}

public class Node2
{
    [XmlElement("Attrib21")]
    public string Attrib21 { get; set; }
    [XmlElement("Attrib22")]
    public string Attrib22 { get; set; }
}
public class Node3
{
    [XmlElement("Attrib31")]
    public string Attrib31 { get; set; }
    [XmlElement("Attrib32")]
    public string Attrib32 { get; set; }
}

以下代码填写数据和序列化

var abc = new XML834.MyRoot();
abc.Node1 = new XML834.Node1[] { new XML834.Node1() { Attrib11 = "a11", Attrib12 = "b12" }, new XML834.Node1() { Attrib11 = "c11", Attrib12 = "c12" } };
abc.Node2 = new XML834.Node2[] { new XML834.Node2() { Attrib21 = "a21", Attrib22 = "b22" }, new XML834.Node2() { Attrib21 = "c21", Attrib22 = "c22" } };
abc.Node3 = new XML834.Node3[] { new XML834.Node3() { Attrib31 = "a31", Attrib32 = "b32" }, new XML834.Node3() { Attrib31 = "c31", Attrib32 = "c32" } };

string xmlString = null;
using (MemoryStream memoryStream = new MemoryStream())
using (XmlTextWriter xmlTextWriter = new XmlTextWriter(memoryStream, Encoding.UTF8))
{
    XmlSerializer xs = new XmlSerializer(typeof(XML834.MyRoot));
    xs.Serialize(xmlTextWriter, abc);
    MemoryStream memoryBaseStream;
    memoryBaseStream = (MemoryStream)xmlTextWriter.BaseStream;
    UTF8Encoding encoding = new UTF8Encoding();
    xmlString = encoding.GetString(memoryBaseStream.ToArray());
    memoryBaseStream.Dispose();
    xmlTextWriter.Close();
    memoryStream.Close();
    Console.WriteLine(xmlString);
}

我得到的输出是

 <?xml version="1.0" encoding="utf 8" ?> 
<MyRoot xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema instance">
<Node1>
  <Attrib11>a11</Attrib11> 
  <Attrib12>b12</Attrib12> 
</Node1>
<Node1>
  <Attrib11>c11</Attrib11> 
  <Attrib12>c12</Attrib12> 
</Node1>
<Node2>
  <Attrib21>a21</Attrib21> 
  <Attrib22>b22</Attrib22> 
</Node2>
<Node2>
  <Attrib21>c21</Attrib21> 
  <Attrib22>c22</Attrib22> 
</Node2>
<Node3>
  <Attrib31>a31</Attrib31> 
  <Attrib32>b32</Attrib32> 
</Node3>
<Node3>
  <Attrib31>c31</Attrib31> 
  <Attrib32>c32</Attrib32> 
</Node3>
</MyRoot>

我正在尝试指定数组项的顺序。是否可以获得此输出?

 <?xml version="1.0" encoding="utf 8" ?> 
<MyRoot xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema instance">
<Node1>
  <Attrib11>a11</Attrib11> 
  <Attrib12>b12</Attrib12> 
</Node1>
<Node2>
  <Attrib21>a21</Attrib21> 
  <Attrib22>b22</Attrib22> 
</Node2>
<Node3>
  <Attrib31>c31</Attrib31> 
  <Attrib32>c32</Attrib32> 
</Node3>
<Node1>
  <Attrib11>c11</Attrib11> 
  <Attrib12>c12</Attrib12> 
</Node1>
<Node2>
  <Attrib21>c21</Attrib21> 
  <Attrib22>c22</Attrib22> 
</Node2>
<Node3>
  <Attrib31>a31</Attrib31> 
  <Attrib32>b32</Attrib32> 
</Node3>
</MyRoot>

3 个答案:

答案 0 :(得分:2)

您需要一个不同的类结构。更像是这样:

[XmlRoot("MyRoot")]
public class MyRoot
{
    public MyNode[] MyNodes {get;set;}
}

public class MyNode
{
    [XmlElement("Node1")]
    public Node1 Node1 { get; set; }
    [XmlElement("Node2")]
    public Node2 Node2 { get; set; }
    [XmlElement("Node3")]
    public Node3 Node3 { get; set; }
}

现在,这将为您提供正确的订单,但也会为您的节点提供额外的元素&#34;。我不记得如何摆脱它。在[XmlText]媒体资源上尝试[XmlElement]MyNodes

答案 1 :(得分:2)

我建议使用xelement并自定义您的序列化

public class Wrapper
{
    [XmlElement("Node1")]
    public Node1 Node1 { get; set; }
    [XmlElement("Node2")]
    public Node2 Node2 { get; set; }
    [XmlElement("Node3")]
    public Node3 Node3 { get; set; }
}


[XmlRoot("MyRoot")]
public class MyRoot
{
          private List<Wrapper> _wrappers;

          public MyRoot() { _wrappers = new List<Wrapper>(); }

   public List<Wrapper> Wrappers
   {
          get { return _wrappers; }
          set { _wrappers = value; }
   }

   public string Serialize()
   {
       if (_wrappers.Any())
       {
           XElement inner = new XElement("MyRoot");
           foreach (var w in _wrappers)
           {

               if (w.Node1 != null)
                   inner.Add(  w.Node1.ToXElement<Node1>() ); 
               if (w.Node2 != null)
                   inner.Add(  w.Node2.ToXElement<Node2>() );
               if (w.Node3 != null)
                   inner.Add( w.Node3.ToXElement<Node3>() );
           }
           return inner.ToString();
       }
       return string.Empty;
   }
}

ToXElement是我从here获得的扩展程序 希望这有帮助!

答案 2 :(得分:0)

在这里,您将了解有关如何设置属性顺序的一些详细信息;

http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlelementattribute.order(v=vs.110).aspx

例如:

[XmlElement(Order = 11)]
public string Attrib11 { get; set; }

@Edit 21:10 - 10-09-2014

如果您执行以下操作对节点进行排序:

[XmlElement(Order = 1)]
public class Node1{
    [XmlElement("Attrib11")]
    public string Attrib11 { get; set; }
    [XmlElement("Attrib12")]
    public string Attrib12 { get; set; }
}

@edit 21:17 如果您尝试这样的事情:

int maxLength = Math.Max(node1.length, node2.length, node3.length);
for(int i = 0; i < maxLength; i++){
serialize node1[i];
serialize node2[i];
serialize node3[i];
}