使用C#XmlSerializer对数组元素进行额外包装

时间:2015-08-12 02:00:14

标签: c# arrays xml serialization

我有以下课程:

namespace XmlSerializerTest
{
    using System;
    using System.Collections.Generic;
    using System.Xml.Serialization;

    [Serializable]
    [XmlRoot( Namespace = "My:NS" )]
    [XmlType( Namespace = "My:NS" )]
    [XmlInclude( typeof( Command ) )]
    [XmlInclude( typeof( ImSession ) )]
    public class CommandBase
    {
        [XmlAttribute]
        public string Version { get; set; }
    }

    [Serializable]
    [XmlType( Namespace = "My:NS" )]
    [XmlInclude( typeof( ImSession[ ] ) )]
    public class Command : CommandBase
    {
        [XmlArray]
        [XmlArrayItem( typeof( ImSession ) )]
        public object[ ] Content { get; set; }
    }

    [Serializable]
    [XmlType( Namespace = "My:NS" )]
    public class ImSession
    {
        [XmlElement]
        public string ClientId { get; set; }

        [XmlElement]
        public DateTime StartTime { get; set; }

        [XmlArray]
        public List<Matrix.Xmpp.Client.Message> Messages { get; set; }
    }
}

我使用以下代码序列化Command对象:

        XmlSerializer ser = new XmlSerializer( typeof( CommandBase ) );

        Command c = new Command
        {
            Version = "TEST",
            Content = new object[ ]
                                  {
                                      new ImSession
                                      {
                                          ClientId = "Client A",
                                          StartTime = DateTime.Today,
                                          Messages = {
                                                         new Matrix.Xmpp.Client.Message( "a@b.com/c" ) { Body = "TEST BODY A" },
                                                         new Matrix.Xmpp.Client.Message( "a@b.com/c" ) { Body = "TEST BODY B" }
                                                     }
                                      },
                                      new ImSession
                                      {
                                          ClientId = "Client B",
                                          StartTime = DateTime.Now,
                                          Messages =
                                                     {
                                                         new Matrix.Xmpp.Client.Message( "c@b.com/a" ) { Body = "TEST BODY C" },
                                                         new Matrix.Xmpp.Client.Message( "c@b.com/a" ) { Body = "TEST BODY D" }
                                                     }
                                      }
                                  }
        };

        ser.Serialize( Console.Out, c );

这导致以下XML,相同的序列化程序无法正确反序列化:

<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">

  <Content>
    <ImSession>
      <ClientId>Client A</ClientId>
      <StartTime>2015-08-11T00:00:00-04:00</StartTime>
      <Messages>
        <Message>
          <message to="a@b.com/c" xmlns="jabber:client">
            <body>TEST BODY A</body>
          </message>
        </Message>
        <Message>
          <message to="a@b.com/c" xmlns="jabber:client">
            <body>TEST BODY B</body>
          </message>
        </Message>
      </Messages>
    </ImSession>
    <ImSession>
      <ClientId>Client B</ClientId>
      <StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
      <Messages>
        <Message>
          <message to="c@b.com/a" xmlns="jabber:client">
            <body>TEST BODY C</body>
          </message>
        </Message>
        <Message>
          <message to="c@b.com/a" xmlns="jabber:client">
            <body>TEST BODY D</body>
          </message>
        </Message>
      </Messages>
    </ImSession>
  </Content>
</CommandBase>

反序列化时,Messages集合为空时会发生什么。 我认为问题是额外的&#34;消息&#34;实际&#34;消息周围的包装元素&#34;元素。 如果我将它更改为一个对象数组,它不再是null,而是包含正确数量的对象,但包括那个额外的包装器。

如何摆脱消息元素周围的额外Message元素?

注意我正在使用Matrix XMPP库(在NuGet上可用)来获取该Message类。

我想要实现的XML是:

<?xml version="1.0" encoding="utf-8"?>
<CommandBase xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xsi:type="Command" Version="TEST" xmlns="My:NS">

  <Content>
    <ImSession>
      <ClientId>Client A</ClientId>
      <StartTime>2015-08-11T00:00:00-04:00</StartTime>
      <Messages>
        <message to="a@b.com/c" xmlns="jabber:client">
          <body>TEST BODY A</body>
        </message>
        <message to="a@b.com/c" xmlns="jabber:client">
          <body>TEST BODY B</body>
        </message>
      </Messages>
    </ImSession>
    <ImSession>
      <ClientId>Client B</ClientId>
      <StartTime>2015-08-11T21:55:18.4624832-04:00</StartTime>
      <Messages>
        <message to="c@b.com/a" xmlns="jabber:client">
          <body>TEST BODY C</body>
        </message>
        <message to="c@b.com/a" xmlns="jabber:client">
          <body>TEST BODY D</body>
        </message>
      </Messages>
    </ImSession>
  </Content>
</CommandBase>

以下是同一对象的反序列化代码:

StringBuilder sb = new StringBuilder( );
ser.Serialize( new StringWriter( sb ), c );
object d = ser.Deserialize( new StringReader( sb.ToString( ) ) );

在调试器中检查d表明它实际上是一个Command对象,其中包含ImSessions,并且每个的Messages数组中都有对象,它声称是Matrix.Xmpp.Client。消息,但其所有属性为null(与xml匹配),除了它们的私有子节点集合,其中包含实际的Message对象,并具有所需的所有属性。

0 个答案:

没有答案