2

我有一个 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 中做到这一点?

4

3 回答 3

3

您应该使用像 LINQ to XML 这样的 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元素本身也无效,则必须相应地修改代码。

于 2013-04-10T01:17:35.370 回答
-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());
于 2013-04-10T00:07:38.430 回答
-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...
                        }
                    }
                }
            }
        }
    }
}
于 2013-04-09T23:26:54.843 回答