Cannot read xml response data that returned from web server
Hi,
I need to parse the xml response data that are returned from web server. I got the response data back in correct format. However, I got this error when I try to load the xml response data by using the loadXml().
Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it.
The returned reponse like this:
<?xml version="1.0" encoding="UTF-8"?>
<connector_ret>
<function name="search">
<row id="1">
<col id="1">value_1</col>
<col id="2">value_2</col>
<col id="3">value_3</col>
<col id="4">value_4</col>
<col id="5">value_5</col>
<col id="6">value_6</col>
<col id="7">value_7</col>
<col id="8">value_8</col>
<col id="9">date_1</col>
<col id="10">date_2</col>
<col id="11">value_11</col>
<col id="12">value_12</col>
<col id="13">value_13</col>
</row>
</function>
</connector_ret>
My codes to parse the reponse are:
protected void processResponse(System.Net.HttpWebResponse oWebResp)
{
Trace.Warn("Start Processing response");
string strResp = null;try
{
byte[] respBytes = readServiceResponse(oWebResp);
strResp = System.Text.UTF8Encoding.UTF8.GetString(respBytes);retRespLabel.Text = strResp; //verify the returned response data
System.Xml.XmlDocument oRespDoc = new System.Xml.XmlDocument();
oRespDoc.LoadXml(strResp);
//select the row node
System.Xml.XmlNode oRowNode = oRespDoc.DocumentElement.SelectSingleNode("function/row");
// retrieve the individual column value.
if (null != oRowNode)
{
System.Xml.XmlNode oColNode1 = oRowNode.ChildNodes[0];
retContactIDLabel.Text = oColNode1.InnerText;System.Xml.XmlNode oColNode2 = oRowNode.ChildNodes[1];
retContactNameLabel.Text = oColNode2.InnerText;System.Xml.XmlNode oColNode3 = oRowNode.ChildNodes[2];
retContactEmailLabel.Text = oColNode3.InnerText;System.Xml.XmlNode oColNode8 = oRowNode.ChildNodes[7];
retUserRoleLabel.Text = oColNode8.InnerText;}
else
{
Trace.Warn("oRowNode is empty...");
}
}
catch (Exception e)
{
Trace.Warn("error 1001:" + e.Message);
return;
}Trace.Warn("End Processing response");
}
private byte[] readServiceResponse(System.Net.HttpWebResponse oWebResp)
{
Trace.Warn("Starting readServiceResponse...");
System.IO.MemoryStream memStream = new System.IO.MemoryStream();const int BUFFER_SIZE = 4096;
int iRead = 0;
int idx = 0;
Int64 iSize = 0;
memStream.SetLength(BUFFER_SIZE);
memStream.Position = 0;
while (true)
{
byte[] reqBuffer = new byte[BUFFER_SIZE];
try
{
iRead = oWebResp.GetResponseStream().Read(reqBuffer, 0, BUFFER_SIZE);
}
catch (System.Exception e)
{
System.Diagnostics.Debug.WriteLine(e.Message);
Trace.Warn("getResponse error message: " + e.Message);
}if (iRead == 0)
{
break;
}iSize += iRead;
memStream.SetLength(iSize);
memStream.Write(reqBuffer, 0, iRead);
idx += iRead;
}byte[] content = memStream.ToArray();
memStream.Close();Trace.Warn("End readServiceResponse...");
return content;
}
Please advice how to resolve it? Need help badly. Thanks a lot!
All Replies
- Try the following..
private byte[] readServiceResponse(System.Net.HttpWebResponse oWebResp) { Trace.Warn("Starting readServiceResponse..."); System.IO.MemoryStream memStream = new System.IO.MemoryStream(); const int BUFFER_SIZE = 4096; int iRead = 0; int idx = 0; Int64 iSize = 0; memStream.SetLength(BUFFER_SIZE); memStream.Position = 0; Stream responseStream = null; while (true) { byte[] reqBuffer = new byte[BUFFER_SIZE]; try { if (responseStream == null) responseStream = oWebResp.GetResponseStream(); iRead = responseStream.Read(reqBuffer, 0, BUFFER_SIZE); } catch (System.Exception e) { System.Diagnostics.Debug.WriteLine(e.Message); Trace.Warn("getResponse error message: " + e.Message); } if (iRead == 0) { break; } iSize += iRead; memStream.Write(reqBuffer, 0, iRead); idx += iRead; } byte[] content = memStream.ToArray(); memStream.Close(); Trace.Warn("End readServiceResponse..."); return content; }I havent stepped through your code, but I think that setting the length on the memorystream again and again might be causing data truncation. Also yyou do not need to get the requestStream again and again.
feroze
--
My blog
Instruction on how to create a tracelog with your System.Net application
Hi Feroze,
Thank you for your help. However, I am still getting the same error message by using your function readServiceResponse(). I think the problem is on the xml string have some bad characters.
I actually fix the problem by writing a function to trim off unwanted characters(hidden) before <?xml ...> tab and any whitespaces or tabs between the element nodes. I find a useful link here:
http://neilkilbride.blogspot.com/2008/04/removing-xmldocument-white-space-c.html
Here is my working codes:
[Note: I am using my original readServiceResponse()]
protected void processResponse(System.Net.HttpWebResponse oWebResp)
{
Trace.Warn("Start Processing response");
string strResp = null;try
{
byte[] respBytes = readServiceResponse(oWebResp);
strResp = System.Text.UTF8Encoding.UTF8.GetString(respBytes);
string xmlString = cleanupXmlString(strResp);
cleanXmlbox.Text = xmlString;System.Xml.XmlDocument oRespDoc = new System.Xml.XmlDocument();
oRespDoc.LoadXml(xmlString);
System.Xml.XmlNode oRowNode = oRespDoc.DocumentElement.SelectSingleNode("function/row");if (null != oRowNode)
{
System.Xml.XmlNode oColNode1 = oRowNode.ChildNodes[0];
retContactIDLabel.Text = oColNode1.InnerText;System.Xml.XmlNode oColNode2 = oRowNode.ChildNodes[1];
retContactNameLabel.Text = oColNode2.InnerText;System.Xml.XmlNode oColNode3 = oRowNode.ChildNodes[2];
retContactEmailLabel.Text = oColNode3.InnerText;System.Xml.XmlNode oColNode8 = oRowNode.ChildNodes[7];
retUserRoleLabel.Text = oColNode8.InnerText;}
else
{
Trace.Warn("oRowNode is empty...");
}
}
catch (Exception e)
{
Trace.Warn("error 1001:" + e.Message +"\n" + e.StackTrace);
}Trace.Warn("End Processing response");
}private string cleanupXmlString(string strXML)
{
Trace.Warn("start cleanupXmlString()...");
int startPos = strXML.IndexOf("<?xml ");
string newString = null;if (startPos > 0)
{
Trace.Warn("Index posistion..." + startPos);
//Trim off any unwanted characters before <?xml
newString = strXML.Substring(startPos);
}
else
{
newString = strXML;
}// Remove inner Xml whitespace
Regex regex = new Regex(@">\s*<");
string cleanedXml = regex.Replace(newString, "><");Trace.Warn("end cleanupXmlString()...");
return cleanedXml;
}


