简体   繁体   English

使用NetworkStream使用XPathDocument读取XML

[英]Reading XML using XPathDocument using NetworkStream

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? 我认为这是由于XPathDocument仍在等待数据,但是如何防止呢?

Due to server didn't close connection after sending whole XML (connection remaining open for future communication) XPathDocument still waits for data. 由于服务器在发送整个XML后未关闭连接(连接保持打开状态,以便将来进行通信),XPathDocument仍在等待数据。 Server does not provide any other data to determine if XML transfer is completed. 服务器不提供任何其他数据来确定XML传输是否完成。 However it is possible to check is whole XML is received by root tag ending. 但是,可以检查根标记结尾是否接收到整个XML。 XPathDocument dosen't look for root tag ending, so this solution is bit tricky, but works. XPathDocument不会寻找根标记的结尾,因此此解决方案有些棘手,但可以。 I reading stream using XmlReader and reproduce XML by XmlWriter which writes in StringWriter. 我使用XmlReader读取流,并通过用StringWriter编写的XmlWriter再现XML。 At end string output from StringWriter is suppiled to StringReader, which is read by XmlReader. 最后,将来自StringWriter的字符串输出编译为StringReader,由XmlReader读取。 And finnaly, XPathDocument reads data from this XmlReader. 最后,XPathDocument从此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. 非常感谢elgonzo向我指出了这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM