Xml to Byte Array and vice versa

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
Hello,

I am writing a xml based data management program. there is a server and a client working together on a network. the server holds all the xml data and the client calls the server and "ask's" the server for the data, which the server will send over the network.I would like to know how to convert a xml file to a byte array and send it over the network.the server and client are talking to each other , so starting the server and listening are done..so is client connecting.the part I need help with is the conversion. I have attempted to do this and this is the code I wrote..the code converts the data to a byte areay (I think) but I am not sure if I am doing this correctly.

string xmlData = File.ReadAllText(rootPath + "\\ActivityData\\ActivityData.xml");

                    byte[] dataBuffer = Encoding.UTF8.GetBytes(xmlData);
               


                    server.SendTo(R.Name, "V^Activity-" + Convert.ToBase64String(dataBuffer));


now I need to convert it back into xml and save it or load the xml into a datagridview

any help would be appreciated

InkedGFX
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,144
Location
Sydney, Australia
Programming Experience
10+
Remember that all files are bytes to begin with. Let's consider what your code is doing. It converts the original bytes of the file to a String, then it converts that String to Bytes, then it converts those Bytes to a String, then it converts that String to Bytes. That seems just a bit inefficient don't you think? What you should be doing is simply calling File.ReadAllBytes and sending the Byte array that that returns. I don't know what your 'server' object is but the only thing that you can send is Bytes so a base-64 String is going to have to be converted back to Bytes to send, so there's no point creating a base-64 String from a Byte array in the first place.
 

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
thank you for your reply,

so I took your advice and removed the uneeded code , we dont want to convert back n forth ....so i guess my next question is how to convert it back to xml on the client side?

now I have this on the server side
byte[] xmlData = File.ReadAllBytes(rootPath + "\\ActivityData\\ActivityData.xml");


and this is on the client side
  
                   byte[] recData = Encoding.UTF8.GetBytes(msg);
                   string xmlData = Convert.ToBase64String(recData);
                   MessageBox.Show(xmlData);


where msg is the incomming data from the server

I appreciate the help

InkedGFX
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,144
Location
Sydney, Australia
Programming Experience
10+
Assuming that you want the data in a file at the other end, File.WriteAllBytes is the converse to File.ReadAllBytes. Alternatively, you could put anything on top of the NetworkStream at the other end that can read from a Stream, e.g. XmlReader, and read the XML directly.
 

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
Ok , I have writen two methods ...one converts a xml file into a byte array and the other converts the byte array back to xml...I know they both work , I have tested them before sending them over the network...the problem is once the data arrives at the client ....I get an error...the root element has invalid charecters....I think the problem is once the xml is converted to a byte array the send method converts it to a string...so I tried to convert the string into xml with no luck....below is the two methods I wrote to do the conversion form xml to byte and vice versa.

  private byte[] ConvertXmlToByteArray(XmlDocument xml, Encoding encoding)
        {
            using (MemoryStream stream = new MemoryStream())
            {
                XmlWriterSettings settings = new XmlWriterSettings();


                settings.Encoding = encoding;
                settings.OmitXmlDeclaration = true;


                using (XmlWriter writer = XmlWriter.Create(stream, settings))
                {
                    xml.Save(writer);
                }


                return stream.ToArray();
            }
        }




        private XElement ConvertByteArrayToXml(byte[] data)
        {
            XmlReaderSettings settings = new XmlReaderSettings();
           
            using (MemoryStream stream = new MemoryStream(data))
            using (XmlReader reader = XmlReader.Create(stream, settings))
            {
                return XElement.Load(reader);
            }
        }


I guess my question would be , how to convert the data received into a xml document.

Thank You
-InkedGFX
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,144
Location
Sydney, Australia
Programming Experience
10+
Do you THINK that the Send method converts it to a String or do you KNOW that it does? If it does, WHY does it? The only thing that you can actually send over the wire is Bytes so, if your Send method converts your Bytes to a String, it must then convert it back again anyway. That is at best inefficient and at worst it's breaking the whole mechanism.

One thing I will suggest though. I'm not sure whether this is an issue or not but, just in case, reset the read position of your MemoryStream to beginning before loading the XML, which you can do using the Position property or the Seek method.
 

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
Yes! Yes! Yes!

I forgot about the read position....I will try that.....

by the way...Thank you for all your help...I wouldn't of gotten this far if it wasn't for your help.I will let you know if this works.

Thank You
-InkedGFX
 

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
well I tried it with resetting the stream.Position = 0;
but still get an error.....Data at the root level is invalid , line 1 position 1

man we are so close.....

-InkedGFX
 

jmcilhinney

C# Forum Moderator
Staff member
Joined
Apr 23, 2011
Messages
3,144
Location
Sydney, Australia
Programming Experience
10+
So, you're saying that you can those two methods and end up with the same XML as you started with but sending the data over the wire in between causes issues? In that case, I guess you need to look at the data that you're sending and the data that you're receiving and compare the two to see what the difference is. Presumably the data is being truncated somewhere but you'll first have to know what's happening before you can determine where. I'd suggest converting the data to hexadecimal in each case, so you can see each byte. Here are a couple of methods that will convert a byte array to a hexadecimal string and vice versa:
/// <summary>
/// Converts an array of <see cref="byte">bytes</see> into a <see cref="string"/> containing a space-delimited list upper-case hexadecimal digit pairs.
/// </summary>
/// <param name="bytes">
/// The <b>bytes</b> to convert.
/// </param>
/// <returns>
/// A <b>string</b> containing hexadecimal digits.
/// </returns>
private string BytesToHex(byte[] bytes)
{
    return string.Join(" ", bytes.Select(b => b.ToString("X2")));
}

/// <summary>
/// Converts a <see cref="string"/> containing a space-delimited list upper-case hexadecimal digit pairs into an array of <see cref="byte">bytes</see>.
/// </summary>
/// <param name="hex">
/// The <b>string</b> to convert.
/// </param>
/// <returns>
/// An array of <b>bytes</b>.
/// </returns>
private byte[] HexToBytes(string hex)
{
    return hex.Split(' ').Select(s => Convert.ToByte(s, 16)).ToArray();
}
It might also pay to post the code that does the sending and receiving because, if this XML conversion works without that, that must be where the issue is.
 

inkedGFX

Well-known member
Joined
Feb 2, 2013
Messages
142
Programming Experience
Beginner
ok...not sure how I would do this...the data I have is xml file.....which one do I use for which side...probably a stupid question...but Im confused

-InkedGFX
 
Top Bottom