views:

41

answers:

2

In my application I have a PacketList class and Packet class. I'd like to be able to use the serialization helpers on PacketList to come up with something like the desired output, but have no idea what direction to go in.

I am writing a program to imitate a server which has a peculiar protocol for sending data.

Client sends data with format: COMMAND|ARGUMENT_0|ARGUMENT_1|ARGUMENT_2|...|ARGUMENT_N\0. Where COMMAND could be something like MOVE or LOGIN.

The server would respond in the format:

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

Where COMMAND_0 could be something like UPDATE_POSITION or AUTHENTICATED.

Yes, this is a silly way of doing things. No, I don't know why it's done this way. No, I can't change it.

Anyways, I am looking to emulate the way that the server sends the packet back to the client. What I have gotten so far is:

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());

This works properly and outputs:

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

However, I'd like to implement this in a cleaner way.

My PacketList basically contains a list of Packets, and Packet contains a String _Command and String[] _Arguments.

If anyone could guide me in the right direction it would be much appreciated.

+1  A: 

The way you are currently doing it is the best. I would say to use the XmlSerializer and decorate your Packet and PacketList class's properties with the appropriate Xml*Attribute attributes to control the way the output is formatted, but since you need to write attributes corresponding to a collection (p0, p1, p2, etc.) this will not work.

Since you need to write such a weird format, it makes sense to write it manually the way you currently are.

Andrew

Andrew
I thought that I was in the right direction, but it was so complicated I didn't think it could be right. Thanks for the input.
Benjamin Manns
+1  A: 

I second Andrew's answer.

AFAIK, there's no way to do it unless you write your own serializer, since you compose two levels of data elements (with dynamic number of elements!) as attributes in a single XML element. There's no sense doing it, and, well, XmlSerializer needs some sense in order to work using just Reflection.

Ron Klein