Сериализация XML для необычного протокола соединения - PullRequest
0 голосов
/ 09 марта 2010

В моем приложении у меня есть класс PacketList и класс Packet. Я хотел бы иметь возможность использовать помощники сериализации на PacketList, чтобы получить что-то вроде желаемого результата, но не знаю, в каком направлении идти.

Я пишу программу для имитации сервера, который имеет особый протокол для отправки данных.

Клиент отправляет данные в формате: COMMAND|ARGUMENT_0|ARGUMENT_1|ARGUMENT_2|...|ARGUMENT_N\0. Где COMMAND может быть что-то вроде MOVE или LOGIN.

Сервер будет отвечать в формате:

<p c='COUNT'>
    <m p='N' p0='COMMAND_0' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
    <m p='N' p0='COMMAND_1' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
    <m p='N' p0='COMMAND_2' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
    <m p='N' p0='COMMAND_3' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
    ...
    <m p='N' p0='COMMAND_COUNT' p1='ARUGMENT_0' ... pN='ARGUMENT_N'/>
</p>

Где COMMAND_0 может быть что-то вроде UPDATE_POSITION или AUTHENTICATED.

Да, это глупый способ делать вещи. Нет, я не знаю, почему это так. Нет, я не могу это изменить.

В любом случае, я хочу эмулировать способ, которым сервер отправляет пакет обратно клиенту. То, что я получил до сих пор:

XmlWriterSettings _Settings = new XmlWriterSettings {
    OmitXmlDeclaration = true,
    Indent = true
};
StringBuilder _Xml = new StringBuilder();
XmlWriter _Writer = XmlWriter.Create(_Xml, _Settings);
_Writer.WriteStartElement("p");
    _Writer.WriteAttributeString("c", "1");
    _Writer.WriteStartElement("m");
        _Writer.WriteAttributeString("p", "2");
        _Writer.WriteAttributeString("p0", "COMMAND");
        _Writer.WriteAttributeString("p1", "ARGUMENT_0");
        _Writer.WriteAttributeString("p2", "ARGUMENT_1");
    _Writer.WriteEndElement(); // </m>
_Writer.WriteEndElement(); // </p>
_Writer.Flush();
Console.WriteLine(_Xml.ToString());

Это работает правильно и выводит:

<p c="1">
  <m p="2" p0="COMMAND" p1="ARGUMENT_0" p2="ARGUMENT_1" />
</p>

Однако я бы хотел реализовать это более понятным способом.

My PacketList в основном содержит список Packet с, а Packet содержит String _Command и String[] _Arguments.

Если бы кто-нибудь мог направить меня в правильном направлении, это было бы очень признательно.

Ответы [ 2 ]

1 голос
/ 09 марта 2010

Я второй ответ Андрея.

AFAIK, нет никакого способа сделать это, если вы не напишите свой собственный сериализатор, поскольку вы объединяете два уровня элементов данных (с динамическим числом элементов!) Как атрибуты в один элемент XML. Нет никакого смысла делать это, и, ну, XmlSerializer нуждается в некотором смысле, чтобы работать с использованием только Reflection.

1 голос
/ 09 марта 2010

То, как вы сейчас это делаете, является лучшим. Я бы сказал, чтобы использовать XmlSerializer и украсить свойства вашего класса Packet и PacketList с помощью соответствующих атрибутов Xml * Attribute для управления форматированием вывода, но так как вам нужно написать атрибуты, соответствующие коллекции (p0, p1, p2 и т. Д. .) это не сработает.

Так как вам нужно написать такой странный формат, имеет смысл написать его вручную, как вы сейчас.

Andrew

...