订购XML元素以进行序列化

时间:2017-03-10 10:54:58

标签: c# xml serialization

我必须按特定顺序将对象序列化为XML文档。

<?xml version="1.0"?>
<__Root __version="1.1" __encryption="2">
  <__service __serviceType="Test">
  <__inputData>
   <BaseToChange>
    <__name>TestName</__name>
   </BaseToChange>
  </__inputData>
  <__perform> 
   <__eventName>Event</__eventName>
  </__perform>    
  <__inputData>
      <ObjectChanges>
        <Name>Test</Name>
      </ObjectChanges>
    </__inputData>
    <__execute />
    <__requestData>
      <CompletionMsg />
    </__requestData>
  </__service>
</__Root>

我现在遇到的问题是,我无法使用元素List<InputData>序列化Perform

public class Service
{
    [XmlAttribute("__serviceType")]
    public string ServiceType { get; set; }

    [XmlElement("__perform")]
    public Perform Perform { get; set; }

    [XmlElement("__inputData")]
    public List<InputData> InputData{ get; set; }

    [XmlElement("__execute")]
    public Execute Execute { get; set; }

    [XmlElement("__requestData")]
    public RequestData RequestData{ get; set; }

    public Service() { }
}

订单必须如图所示。首先是<__inputData>,然后是<__perform>,然后是剩余的<__inputData>

我已经尝试将属性和XmlElements分开,但是一旦我想用两个具有相同名称的元素序列化,我就会收到错误。

有没有人知道如何做到这一点?

1 个答案:

答案 0 :(得分:0)

您可以利用多态元素功能[XmlElement(Type = typeof(TElement))]以正确的顺序创建包含PerformInputData对象的代理对象数组:

public class Service
{
    [XmlAttribute("__serviceType")]
    public string ServiceType { get; set; }

    [XmlIgnore]
    public Perform Perform { get; set; }

    [XmlIgnore]
    public List<InputData> InputData { get; set; }

    [XmlElement("__perform", Type = typeof(Perform))]
    [XmlElement("__inputData", Type = typeof(InputData))]
    public object[] XmlInputAndPerformance
    {
        get
        {
            var inputData = (InputData ?? Enumerable.Empty<InputData>()).Cast<object>();
            var performData = Perform == null ? Enumerable.Empty<object>() : new object[] { Perform };

            return inputData.Take(1)
                .Concat(performData)
                .Concat(inputData.Skip(1))
                .ToArray();
        }
        set
        {
            if (value == null)
                return;
            var newInputs = value.OfType<InputData>().ToList();
            var newPerform = value.OfType<Perform>().ToList();
            if (newInputs.Count + newPerform.Count != value.Length)
                throw new ArgumentException("Unknown type.");
            if (newPerform.Count > 1)
                throw new ArgumentException("Too many Perform objects.");

            if (newPerform.Count > 0)
                Perform = newPerform[0];
            (InputData = InputData ?? new List<InputData>()).AddRange(newInputs);
        }
    }

    [XmlElement("__execute")]
    public Execute Execute { get; set; }

    [XmlElement("__requestData")]
    public RequestData RequestData { get; set; }

    public Service() { }
}

请注意,原始InputDataPerform属性已标记为[XmlIgnore],并且已添加了两个[XmlElement(name, Type = typeof(TElement))]属性,一个用于InputData,另一个属性用于Perform BackgroundMainMenu(newImageIcon(FirstWindow.class.getResource("/stuff/images/mainMenu.jpg")).getImage());

示例fiddle