2013-04-09 106 views
2

連續記錄我有一個XML文件:解析兩個XML文件

<root type="service"> 
    <Msg Date="03/23/2013 12:00:04 AM">Request'HANDSHAKE'</Msg> 
    <Msg Date="03/23/2013 12:00:04 AM">Response'RSHANDSHAKE'</Msg> 
    <Msg Date="03/23/2013 12:03:04 AM">Request'HANDSHAKE'</Msg> 
    <Msg Date="03/23/2013 12:03:04 AM">Response'RSHANDSHAKE'</Msg> 
    <Msg Date="03/23/2013 01:34:30 PM">Request 'IQ~bbabb3ff2-...DLE~VNECTRECVBDHANDLE'</Msg> 
    <Msg Date="03/23/2013 01:34:30 PM">Response SIQ~7a23da12...RDHANDLE=O000000000014'</Msg> 
</root> 

我要解析的文件,看看每個請求是否後跟的響應。如果沒有迴應,則表示存在錯誤。我怎樣才能在C#和最好的LINQ做到這一點?

+1

到目前爲止你寫了什麼代碼? – Brian 2013-04-09 23:10:50

+1

也許看看[LINQ to XML](http://msdn.microsoft.com/en-us/library/bb387061.aspx)用於使用LINQ讀取XML,但是我不確定XML是否以這種方式保證順序,所以LINQ to XML可能不會保留這一點。 – JakeP 2013-04-09 23:28:35

回答

3

您應該使用XML解析器喜歡的LINQ to XML。就這樣,你的代碼看起來是這樣的:

XDocument doc = XDocument.Load("file.xml"); 
bool isError = (from e1 in doc.Root.Elements() 
       where e1.Value.StartsWith("Request") 
       let e2 = e1.ElementsAfterSelf().FirstOrDefault() 
       where e2 == null || !e2.Value.StartsWith("Response") 
       select e1).Any(); 

這種文學做了你問什麼:每Request元素,它會檢查以下元素存在,是一個Response元素。

如果您有其他要求,例如Response元素本身也是無效的,您將不得不相應地修改代碼。

+0

這個解決方案看起來最好,+1 – Amegon 2013-04-10 02:03:33

+0

我喜歡這個解決方案。這說得通。我會嘗試一下,看看它是否適合我。感謝您的迴應。 – shazia 2013-04-11 17:54:29

+0

謝謝svick這個時尚的解決方案。它像一個魅力。我從來沒有想過可以用LINQ做這麼棒的事情。你能指導我寫一些關於LINQ的好書或文章嗎?再次感謝。 – shazia 2013-04-12 21:26:28

-1

像這樣的工作,我只是測試它在Visual Studio中,肯定有更優雅的方式做使用XPATH過濾器/選擇器的這部分...

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

namespace ParseXML 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      String xmlString = 
     @"<root type=""service""> 
       <Msg Date=""03/23/2013 12:00:04 AM"">Request'HANDSHAKE'</Msg> 
       <Msg Date=""03/23/2013 12:00:04 AM"">Response'RSHANDSHAKE'</Msg> 
       <Msg Date=""03/23/2013 12:03:04 AM"">Request'HANDSHAKE'</Msg> 
       <Msg Date=""03/23/2013 12:03:04 AM"">Response'RSHANDSHAKE'</Msg> 
       <Msg Date=""03/23/2013 01:34:30 PM"">Request 'IQ~bbabb3ff2-...DLE~VNECTRECVBDHANDLE'</Msg> 
       <Msg Date=""03/23/2013 01:34:30 PM"">Response SIQ~7a23da12...RDHANDLE=O000000000014'</Msg> 
      </root>"; 

      // Create an XmlReader 
      using (XmlReader reader = XmlReader.Create(new StringReader(xmlString))) 
      { 
       while (reader.ReadToFollowing("Msg")) 
       { 
        string request = reader.ReadElementContentAsString(); 

        if(reader.ReadToFollowing("Msg")) 
        { 
         string response = reader.ReadElementContentAsString(); 

         if (request.Contains("Request") && response.Contains("Response")) 
         { 
          // Request/Response nodes identified... 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

我喜歡解析xml的解決方案,但是,如果它增加了更多的複雜性,那麼存在出錯結果的風險。您將能夠識別與此有關的第一個錯誤,但是然後請求包含響應並且響應包含請求。如果你解決這個問題,那麼這是一個很好的解決方案。你想檢查請求不包含請求,響應不包含響應,因爲問題是要找到錯誤。 – Amegon 2013-04-09 23:36:32

+0

記錄在問題中的XML片段中不包含彼此,它們是順序的,我的代碼在識別肯定案例時符合問題要求。沙希亞可以從那裏開始,如果相信是一個很好的解決方案,並通過添加錯誤處理和特殊情況處理...或ognore它,並根據需要使用LINQ或XPATH的另一個解決方案完成實施... – 2013-04-09 23:50:35

+0

它適用於您的示例,但作爲我在之前的評論中提到,它也應該是找到錯誤的解決方案。如果刪除一個響應,則不會檢測到以下所有正確的Request..Response。 (因爲然後請求將填充響應,反之亦然) – Amegon 2013-04-10 00:13:15

-1

這裏,對於有效的解決方案有效的情況下,也爲錯誤,也給你確切的金額:

String xmlString = @"<root type=""service""> 
     <Msg Date=""03/23/2013 12:00:04 AM"">Request'HANDSHAKE'</Msg> 
     <Msg Date=""03/23/2013 12:00:04 AM"">Response'RSHANDSHAKE'</Msg> 
     <Msg Date=""03/23/2013 12:03:04 AM"">Request'HANDSHAKE'</Msg> 
     <Msg Date=""03/23/2013 12:03:04 AM"">Response'RSHANDSHAKE'</Msg> 
     <Msg Date=""03/23/2013 01:34:30 PM"">Request 'IQ~bbabb3ff2-...DLE~VNECTRECVBDHANDLE'</Msg> 
     <Msg Date=""03/23/2013 01:34:30 PM"">Response SIQ~7a23da12...RDHANDLE=O000000000014'</Msg> 
    </root>"; 

    String[] data = xmlString.Split(new string[] { "/Msg"}, StringSplitOptions.None); 

    int errors = 0; 
    Boolean secondLine = false; 
    for (int i = 0; i+1 < data.Length; i ++) 
    { 
     if (secondLine) 
     { 
      if (!data[i].Contains("Response")) 
      { 
       errors += 1; 
      } 
      secondLine = false; 
     } 
     else 
     { 
      if (!data[i].Contains("Request")) 
      { 
       errors += 1; 
      } 
      else 
      { 
       secondLine = true; 
      } 
     } 
    } 
    if (secondLine) { errors += 1; } 

    System.Windows.Forms.MessageBox.Show("Errors: " + errors.ToString()); 
+0

爲什麼downvote在這裏? – Amegon 2013-04-10 00:29:51

+1

您可能第一次沒有得到它:**不要手動解析XML,請使用XML解析器**。 – svick 2013-04-10 01:05:53