Oleg,
Thank you for your suggestions. Using the depth property, I am able to
identify when I have a complete node.
Alexander,
I do not have my XmlReader bound to my TCP stream. Rather I point the
XmlReader to a string buffer. When I receive data from the server, I cast
the read into a global string variable. Each time I get data from the
socket, I concatenate this to my global string (I suppose I could be using a
stream instead of a string). I then try to look for a complete node. If I
find a complete node, I spawn a thread and call a procedure that loads the
complete node into an XmlDocument. Afterwards, I clear that xml from the
buffer and try to find another complete node until the XmlReader returns an
error. Here is my code:
'XmlFrag -> global string var
'Each time I receive data from the socket:
XmlFrag = XmlFrag & str 'str = read from socket converted to string
Do While XmlFrag <> "" 'Will run in loop until I parse the entire buffer
or XmlReader throws an exception
parseXML
End While
Private sub parseXml
Try
Dim nt as NameTable = new NameTable
Dim nsmgr as XmlNamespaceMan ager = new XmlNamespaceMan ager(nt)
Dim context as XmlParserContex t = new XmlParserContex t(Nothing, nsmgr,
Nothing, XmlSpace.None)
Dim reader as XmlTextReader = new XmlTextReader(X mlFrag,
XmlNodeType.Ele ment, context)
Dim sXML as string = ""
While (reader.Read())
Select Case reader.NodeType
Case XmlNodeType.Ele ment
If reader.Depth = 0 then 'If I am at the beginning of a
complete node
sXML = reader.ReadOute rXml() 'Try to read to the end
of the node, if an error is thrown, it means there was not a complete node
in the read
ThreadPool.Queu eUserWorkerItem (AddressOf routeXMLString,
sXML) 'spawn thread to deal with xml (load into XmlDocument)
XmlFrag = XmlFrag.Remove( 0, sXML.length) 'Clear
string of parsed xml
reader.Close()
Exit While
End if
End Select
End While
Catch ex As Exception
Throw New Exception(ex.Me ssage)
End Try
End Sub
You also might want to check out this SAX parser for .NET at:
http://www.xmlforasp.net/codeSection.aspx?csID=36
-Thomas
"Alexander Gnauck" <al*********@gm x.de> wrote in message
news:bg******** ****@ID-112594.news.uni-berlin.de...
Hello,
Sorry if this has been posted before...
I am receiving XML messages over a TCP client. Messages vary in size
and sometimes can arrive in groups. Thus, I am not guaranteed to
receive a full message in a single read from my socket.
I am loading each message into an XmlDocument after it arrives. I
need a way to make sure I have a complete XML message before I load
it into an XmlDocument or it will throw an exception. I am currently
finding complete messages by turning each read into a string and
manually look for closing tags. Surely there is an easier way to
accomplish this, perhaps with an XmlReader or XmlTextReader?
im working on the same stuff. First i took XMLDocument to validate if have
a complete node that i can parse. But the XmlDocument is very very slow.
Especially on compact Framework. Thats the Reason why im working at the
moment at a better and faster way with the XmlReader or XmlTextReader. You
must Read in a XmlReader and check the depth of the Reader. Then you know
when you have a complete node. The XmlReader must be bound to a Stream. My
problem is that i found no way for now to create a XmlDocument from the
Reader when i know that i have a complete now since this position.
Below is the code of my old Socket Queue class. xmlReader is a small
wrapper class here for the XmlDocument. Can send it to you when it helps.
Alex
public class SocketQueue
{
// static variable where we spool the socket Data when Streams
// are not partial
private static string m_XML = "";
public SocketQueue(str ing strSocket, Session s)
{
XML_Node xmlReader = new XML_Node(m_XML + strSocket);
if ( xmlReader.Valid == true )
{
// We have one valid XML Node
// send it to the parser
s.RaiseOnIncomi ngXML(m_XML + strSocket);
Parser parse = new Parser(m_XML + strSocket, s);
m_XML = "";
}
else
{
//XML_Node xmlReader2 = new XML_Node("<dumm y>" + strSocket +
"</dummy>");
XML_Node xmlReader2 = new XML_Node("<dumm y>" + m_XML + strSocket +
"</dummy>");
if(xmlReader2.V alid == true)
{
// we have more than 1 node
// get all childnodes and send them to the Parser
m_XML = "";
for (int i = 0; i <
xmlReader2.XMLO bj.ChildNodes[0].ChildNodes.Cou nt; i++)
{
s.RaiseOnIncomi ngXML(xmlReader 2.XMLObj.ChildN odes[0].ChildNodes[i].OuterXml) ;
Parser parse = new
Parser(xmlReade r2.XMLObj.Child Nodes[0].ChildNodes[i].OuterXml,s);
}
}
else
{
// we have no complete XML Node
m_XML = m_XML + strSocket;
}
}
}
}
}