Question

This hangs application:

XPathDocument xPathDocument = new XPathDocument(networkStream);

I think this is due to XPathDocument is still waiting for data, but how to prevent it?

Was it helpful?

Solution

Due to server didn't close connection after sending whole XML (connection remaining open for future communication) XPathDocument still waits for data. Server does not provide any other data to determine if XML transfer is completed. However it is possible to check is whole XML is received by root tag ending. XPathDocument dosen't look for root tag ending, so this solution is bit tricky, but works. I reading stream using XmlReader and reproduce XML by XmlWriter which writes in StringWriter. At end string output from StringWriter is suppiled to StringReader, which is read by XmlReader. And finnaly, XPathDocument reads data from this XmlReader. Here is example code:

        XmlReader xmlReader = XmlReader.Create(networkStream);
        StringWriter stringWriter = new StringWriter();
        XmlWriter xmlReadBuffer = XmlWriter.Create(stringWriter);

        while (xmlReader.Read())
        {
            switch (xmlReader.NodeType)
            {
                case XmlNodeType.XmlDeclaration:
                    xmlReadBuffer.WriteStartDocument();
                    break;
                case XmlNodeType.Element:
                    xmlReadBuffer.WriteStartElement(xmlReader.Name);
                    if (xmlReader.HasAttributes)
                        xmlReadBuffer.WriteAttributes(xmlReader, false);
                    if (xmlReader.IsEmptyElement)
                        goto case XmlNodeType.EndElement;
                    break;
                case XmlNodeType.EndElement:
                    if (xmlReader.Depth == 0)
                    {
                        xmlReadBuffer.WriteEndElement();
                        xmlReadBuffer.WriteEndDocument();
                        goto EndXml;
                    }
                    xmlReadBuffer.WriteEndElement();
                    break;
                case XmlNodeType.Text:
                    xmlReadBuffer.WriteString(xmlReader.Value);
                    break;
                default:
                    break;
            }
        }

    EndXml:
    xmlReadBuffer.Flush();

    XPathDocument xPathDocument = new XPathDocument(XmlReader.Create(new StringReader(stringWriter.ToString())));

Big thanks for elgonzo who pointed me to this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top