2013-04-09 105 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