2017-05-14 55 views
0

我需要解析來自TCP/IP連接的標準XML結構。數據保存爲字符串變量。這意味着在任何給定的時間裏,我手上的數據都可能是不完整的(一個不完整的XML結構),或者是一個完整的XML結構(剩餘不完整)(下一個XML結構的開始)。解析來自TCP/IP連接的XML字符串

大部分結構都沒有「空」:

<Message> 
    <Param1 value = "val1"/> 
    <Param2 value = "val2"/> 
</Message> 

但也有「空」的:

<Message status="ack" /> 

因此,只要尋找</Message>,使分裂沒有好足夠。

如何從下一個部分結構中分出完整的結構?除了爲此創建自己的狀態機並逐字節地檢查外,是否有更簡潔的解決方案?

+0

也許這可以幫助:http://stackoverflow.com/questions/55828/how-does-one-parse-xml-files?rq=1 –

+0

這裏最大的問題是部分xml結構不是xml結構,它們是無效的標記。無論如何,你可以擺脫xml? –

+1

聽起來你應該在更高級別的協議上工作,以便知道需要多少字節,並且可以清楚地區分文檔。這是你控制的協議嗎? –

回答

0

您可以使用字典的每個消息

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Xml; 
using System.Xml.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      string input = 
       "<Message>" + 
        "<Param1 value = \"val1\"/>" + 
        "<Param2 value = \"val2\"/>" + 
       "</Message>" + 
       "<Message>" + 
        "<Param1 value = \"val1\"/>" + 
        "<Param2 value = \"val2\"/>" + 
       "</Message>"; 


      XElement message = 
       new XElement("Root", input); 

      var results = message.Elements("Message") 
       .Where(x => x.HasElements) 
       .Select(x => x.Elements() 
        .GroupBy(y => y.Name.LocalName, z => z) 
        .ToDictionary(y => y.Key, z => (string)z.FirstOrDefault() 
         .Attribute("value"))) 
       .ToList(); 
     } 
    } 
} 
+0

謝謝你的建議jdweng。但是,似乎XElement.Parse(輸入);嘗試解析不完整的XML結構時引發異常。 –

+1

使用XML,您必須等待所有數據的發生。 xml標籤必須關閉。使用TCP時,消息被分解爲最大大小爲1500字節的數據報。因此,首先使用TCP,您需要知道每個消息何時終止,並繼續讀取TCP數據,直到收到整個消息。在這種情況下,您可以將消息解析爲搜索作爲終結符。 – jdweng

+0

jdweng,我本來可以搜索是不是'空'節點,如: