Converting string array to string (and vice-versa) for storing via XML I'm using XML to store data and I need to store a string array in it. The best way (that I can think of) to store a string array is by converting it to a single string. In order to do that, I'm using string.Join to join the strings with \0 and then use Base64 so that the \0 (and any other special character) can be retrieved easier. Because it's possible that a string in a array already has \0 in it (causing another string to be the array when they're converted back to an array), I'm escaping the existing \0 by first adding another backslash to existing backslashes and changing \0 to \\0. Is there any better way to do this? Should I be using \r\n instead (but wouldn't that also be the same as using \0)? I should also note that its so I can use IXmlSerializable and it is also storing byte[], uint, ulong and string in the XML as well.

Retrieving String Array (Via XML)

this.Name = reader.GetAttribute("Name");

string strType = reader.GetAttribute("Type");

byte[] buffer = new byte[1000];
int readBytes = 0;
MemoryStream ms = new MemoryStream();
BinaryWriter bw = new BinaryWriter(ms);
while ((readBytes = reader.ReadElementContentAsBase64(buffer, 0, 50)) &gt; 0)
{
    bw.Write(buffer, 0, readBytes);
}

bw.Close();

List&lt;string&gt; unescapedStrs = new List&lt;string&gt;();
string[] val = strValue.Split('\0');
string newStr;

foreach (string s in val)
{
    newStr = Regex.Replace(s, @"([^\\])(\\0)", "$1\0").Replace("\\\\", "\\");

    unescapedStrs.Add(newStr);
}

if (val.Length &gt; 0)
    this.Value = unescapedStrs.ToArray();


Storing String Array (Via XML)

writer.WriteAttributeString("Name", this.Name);

writer.WriteAttributeString("Type", this.Type);

string strValue = string.Empty;

string[] val = (string[])this.Value;

List&lt;string&gt; escapedStrs = new List&lt;string&gt;();

foreach (string s in val)
{
    string newStr = s;

    // Escape backslashes so existing \\0 don't get mixed up
    if (newStr.IndexOf('\\') &gt; 0)
        newStr = newStr.Replace("\\", "\\\\");

    // If theres NULL chars in strings already, escape them
    if (newStr.IndexOf('\0') &gt; 0)
        newStr = newStr.Replace("\0", "\\0");

    escapedStrs.Add(newStr);
}

strValue = string.Join("\0", escapedStrs.ToArray());

int byteLen = Encoding.Unicode.GetByteCount(strValue);
byte[] bytes = Encoding.Unicode.GetBytes(strValue);
writer.WriteBase64(bytes, 0, byteLen);
My first reaction is: don't do this.

By creating your own encoding for an array of strings, your XML is not going to be (easily) consumable by other programs. By Base64 encoding your strings, your XML is not going to be human-readable.

These are two major benefits of XML, and if you're willing to sacrifice them, maybe XML is not the right format. If the serialized data is only going to be consumed by the same program, binary serialization would be a better option.

That said, if you want to serialize a list of strings to XML, this is what I would recommend:

public class Email
{
    private static readonly XmlSerializer Serializer = new XmlSerializer(typeof(Email));

    [XmlArrayItem("Attachment")]
    public List&lt;string&gt; Attachments { get; set; }

    public XDocument ToXDocument()
    {
        var document = new XDocument();
        using (var writer = document.CreateWriter())
        {
            Serializer.Serialize(writer, this);
        }

        return document;
    }
}


And some sample client code:

var email = new Email
{
    Attachments = new List&lt;string&gt; { "&lt;hello&gt;&lt;/hello&gt;", "asdf" }
};
var xml = email.ToXDocument().ToString();
Console.WriteLine(xml);


This will output

&lt;Email xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"&gt;
  &lt;Attachments&gt;
    &lt;Attachment&gt;&amp;lt;hello&amp;gt;&amp;lt;/hello&amp;gt;&lt;/Attachment&gt;
    &lt;Attachment&gt;asdf&lt;/Attachment&gt;
  &lt;/Attachments&gt;
&lt;/Email&gt;


Now, this chokes if the strings contain a null-byte, which you mentioned was a possibility. It's hard to say what to do about this without knowing more about your problem domain. Hopefully, stripping null-bytes is an option for you.

Serializing a byte[] as a Base64-encoded string can be done using a surrogate property:

[XmlIgnore]
public byte[] Bytes { get; set; }

public string BytesBase64
{
    get { return Convert.ToBase64String(this.Bytes); }
    set { this.Bytes = Convert.FromBase64String(value); }
}