3

I have a byte stream like this:

byte[] response =
        {
            69, 90, 69, 45, 88, 77, 76, 45, 77, 115, 103, 48, 50, 60, 77, 101, 115, 115, 97, 103, 101, 62, 13, 10, 32,
            32, 60, 72, 101, 97, 100, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 77, 101, 115, 115, 97, 103, 101, 68,
            97, 116, 101, 62, 50, 48, 49, 48, 48, 51, 50, 52, 60, 47, 77, 101, 115, 115, 97, 103, 101, 68, 97, 116,
            101, 62, 13, 10, 32, 32, 32, 32, 60, 77, 101, 115, 115, 97, 103, 101, 84, 105, 109, 101, 62, 49, 57, 50,
            56, 48, 54, 60, 47, 77, 101, 115, 115, 97, 103, 101, 84, 105, 109, 101, 62, 13, 10, 32, 32, 60, 47, 72,
            101, 97, 100, 101, 114, 62, 13, 10, 32, 32, 60, 66, 111, 100, 121, 62, 13, 10, 32, 32, 32, 32, 60, 84,
            114, 97, 110, 115, 97, 99, 116, 105, 111, 110, 73, 68, 62, 51, 51, 50, 53, 50, 55, 60, 47, 84, 114, 97,
            110, 115, 97, 99, 116, 105, 111, 110, 73, 68, 62, 13, 10, 32, 32, 32, 32, 60, 84, 114, 97, 110, 115, 97,
            99, 116, 105, 111, 110, 78, 117, 109, 98, 101, 114, 62, 49, 50, 49, 48, 52, 55, 48, 60, 47, 84, 114, 97,
            110, 115, 97, 99, 116, 105, 111, 110, 78, 117, 109, 98, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 80,
            104, 111, 110, 101, 78, 117, 109, 98, 101, 114, 62, 54, 51, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 60,
            47, 80, 104, 111, 110, 101, 78, 117, 109, 98, 101, 114, 62, 13, 10, 32, 32, 32, 32, 60, 65, 109, 111,
            117, 110, 116, 62, 48, 48, 48, 48, 48, 48, 50, 53, 48, 48, 60, 47, 65, 109, 111, 117, 110, 116, 62, 13,
            10, 32, 32, 32, 32, 60, 82, 101, 115, 117, 108, 116, 62, 48, 51, 60, 47, 82, 101, 115, 117, 108, 116, 62,
            13, 10, 32, 32, 60, 47, 66, 111, 100, 121, 62, 13, 10, 60, 47, 77, 101, 115, 115, 97, 103, 101, 62
        };

I want to extract the xml out of it. Tried the following:

XmlDocument doc2 = new XmlDocument();
        MemoryStream ms = new MemoryStream(response);
        doc2.Load(ms);

But got an exception like:

An unhandled exception of type 'System.Xml.XmlException' occurred in System.Xml.dll

Additional information: Data at the root level is invalid. Line 1, position 1.

I'm really new to this xml stuff, what should doc2.load() method do? will it create any xml file which I can read later, will it be just a in memory collection?

2 Answers 2

4

The problem is that your byte [] array represents a string that has some non-XML characters at the beginning. If I do

string s;
using (var ms = new MemoryStream(response))
using (var reader = new StreamReader(ms))
{
    s = reader.ReadToEnd();

    Console.WriteLine(s);
}

I see

EZE-XML-Msg02<Message>
  <Header>
    <MessageDate>20100324</MessageDate>
    <MessageTime>192806</MessageTime>
  </Header>
  <Body>
    <TransactionID>332527</TransactionID>
    <TransactionNumber>1210470</TransactionNumber>
    <PhoneNumber>639999999999</PhoneNumber>
    <Amount>0000002500</Amount>
    <Result>03</Result>
  </Body>
</Message>

The EZE-XML-Msg02 has to be removed first. The best way to do this would be not to store it in the XML in the first place. But if you somehow cannot prevent it from being included in the XML, you could do:

XmlDocument doc2 = new XmlDocument();
using (var ms = new MemoryStream(response))
using (var reader = new StreamReader(ms))
{
    while (!reader.EndOfStream && reader.Peek() > -1 && (char)reader.Peek() != '<')
        reader.Read();
    if (!reader.EndOfStream)
        doc2.Load(reader);
}
Sign up to request clarification or add additional context in comments.

Comments

3

That's because it is invalid XML. Your full string is the following:

EZE-XML-Msg02<Message>
  <Header>
    <MessageDate>20100324</MessageDate>
    <MessageTime>192806</MessageTime>
  </Header>
  <Body>
    <TransactionID>332527</TransactionID>
    <TransactionNumber>1210470</TransactionNumber>
    <PhoneNumber>639999999999</PhoneNumber>
    <Amount>0000002500</Amount>
    <Result>03</Result>
  </Body>
</Message>

The extraneous "EZE-XML-Msg02" is causing the problem. You either want to trim this part off (you could do string.Remove if you know the length that this will be in advance or string.Split(',') and use that to find the length if you don't). Or, better yet, stop it from going into the XML in the first place if possible.

A few side notes at this point. First, Your method of decoding will definitely work, but you probably want to put the MemoryStream inside of a "using" block. Another way of doing the decoding is the following:

string str = ASCIIEncoding.ASCII.GetString(response);

it'll decode the string for you. You can do

doc2.LoadXml(str);

and it'll load the doc for you.

The XmlDocument object itself will, at this point, just be an in-memory collection. You can explicitly save it as a file by calling doc2.Save(filename) if you'd like though.

Also note that some people prefer the LINQ version (XDocument) to XML Document so they can run LINQ queries against it. The XmlDocument object supports XPath querying but that's somewhat inefficient because it can't statically compile the query, it has to be parsed at runtime. Which you use really depends on your specific application though.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.