Я пытаюсь разобрать XML-сообщения, которые отправляются на мое приложение С# через TCP. К сожалению, протокол не может быть изменен, а XML-сообщения не разделены и префикс длины не используется. Кроме того, кодировка символов не является фиксированной, но каждое сообщение начинается с объявления XML <?xml>
. Вопрос в том, как я могу читать одно XML-сообщение за раз, используя С#.
До сих пор я пытался прочитать данные из потока TCP в массив байтов и использовать его через MemoryStream
. Проблема в том, что буфер может содержать более одного XML-сообщения или первое сообщение может быть неполным. В этих случаях я получаю исключение при попытке проанализировать его с помощью XmlReader.Read
или XmlDocument.Load
, но, к сожалению, XmlException
не позволяет мне отличать проблему (кроме синтаксического анализа строки локализованной ошибки).
Я попытался использовать XmlReader.Read
и подсчитать количество узлов Element
и EndElement
. Таким образом, я знаю, когда я закончил читать первое целое XML-сообщение.
Однако есть несколько проблем. Если буфер еще не содержит всего сообщения, как я могу отличить XmlException
от фактически недействительного, не-правильно сформированного сообщения? Другими словами, если перед чтением первого корня EndElement
возникает исключение, как я могу решить, следует ли прервать соединение с ошибкой или собрать больше байтов из потока TCP?
Если исключение не происходит, XmlReader
располагается в начале корня EndElement
. Отбрасывание XmlReader
в IXmlLineInfo
дает мне текущие LineNumber
и LinePosition
, однако прямо не получается получить положение байта, где действительно заканчивается EndElement
. Для этого мне пришлось бы преобразовать массив байтов в строку (с кодировкой, указанную в объявлении XML), искать LineNumber
, LinePosition
и преобразовывать это обратно в смещение байта. Я пытаюсь сделать это с помощью StreamReader.ReadLine
, но считыватель потока не дает открытого доступа к текущей позиции байта.
Все эти швы очень неэлегантные и ненадежные. Интересно, есть ли у вас идеи для лучшего решения. Спасибо.