检查多个 XML 文件 [英] Checking multiple XML files

查看:22
本文介绍了检查多个 XML 文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我从我原来的帖子中重新措辞:我有两个 XML 文件,每个文件都与给定的年份相关.例如,18/19 和 17/18.它们符合相同的结构,下面是来自这些文件之一的小样本.我想要的是,在 C# 中,比较这些文件中的所有记录,其中名、姓、NI 编号和出生日期相同,但学习者参考编号不同.我需要能够进行比较,然后只将这些记录推送到数据表中,这样我就可以将它们推送到电子表格中(我可以做的电子表格位).我目前将以下内容作为起点,但仍然很卡.

I am re-wording this from my original post: I have two XML files, and they are related to a given year each. For example, 18/19 and 17/18. They conform to the same structure and below is small sample from one of these files. What I want is, in C#, to compare all records in these files where the Given Name, the Family Name, the NI Number and the Date of birth are the same, BUT the Learner Ref Number is different. I need to be able to compare, then push only these records into a data table so I can then push them into a spreadsheet (the spreadsheet bit I can do). I currently have the below as a starting block, but am still very much stuck.

首先,我按下了导入按钮:

Firstly, I have my Import button press for which:

        private void Btn_Import_Click(object sender, RoutedEventArgs e)
    {


        ILRChecks.ILRReport.CrossYear();}

然后查看最终将文件推送到我所在位置的类:

Then this goes to look at the Class of which eventually pushes the file to my location:

using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ILRValidation;
using InfExcelExtension;

namespace ILRChecks
{
internal static partial class ILRReport
{
    internal static void CrossYear()
    {
        DataSet ds_CrossYearChecks = 
ILRValidation.Validation.CrossYearChecks(Global.fileNames);

        string output = Path.Combine(Global.foldername, "ULIN_Issues" + 
".xlsx");


        ds_CrossYearChecks.ToWorkBook(output);




    }
}
}

这是我坚持的一点,即寻找差异的过程:

And this is the bit I'm stuck on, which is the production of finding the differences:

using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ILRValidation
{
public static partial class Validation
{
    public static DataSet CrossYearChecks(DataSet ds_CrossYearChecks)
    {
        return CrossYearChecks(ds_CrossYearChecks);
    }

    public static DataSet CrossYearChecks(string[] xmlPath)
    {

        DataSet ds_xmlCrossYear = new DataSet();


        return CrossYearChecks(ds_xmlCrossYear);
    }
}
}

XML:

<Learner>
<LearnRefNumber></LearnRefNumber>
<ULN></ULN>
<FamilyName></FamilyName>
<GivenNames></GivenNames>
<DateOfBirth></DateOfBirth>
<Ethnicity></Ethnicity>
<Sex></Sex>
<LLDDHealthProb></LLDDHealthProb>
<NINumber></NINumber>
<PriorAttain></PriorAttain>
<MathGrade></MathGrade>
<EngGrade></EngGrade>
<PostcodePrior></PostcodePrior>
<Postcode></Postcode>
<AddLine1></AddLine1>
<AddLine3></AddLine3>
<Email></Email>

推荐答案

好吧,您可以递归遍历这两个 XML 文件并记下所有遇到的更改.类似的东西应该会有所帮助:

Well, you can traverse both XML files recursively and write down all the encountered changes. Something like should be helpful:

static string AppendPrefix(string oldPrefix, string addition) =>
    oldPrefix == "" ? addition : $"{oldPrefix}.{addition}";

static void CompareElements(string prefix, XElement d1, XElement d2)
{
    // 1. compare names
    var newPrefix = AppendPrefix(prefix, d1.Name.ToString());
    if (d1.Name != d2.Name)
    {
        Console.WriteLine(
            $"Name mismatch: {newPrefix} != {AppendPrefix(prefix, d2.Name.ToString())}");
        return;
    }

    // 2. compare attributes
    var attrs = d1.Attributes().OrderBy(a => a.Name);
    var unpairedAttributes = new HashSet<XAttribute>(d2.Attributes());
    foreach (var attr in attrs)
    {
        var otherAttr = d2.Attributes(attr.Name).SingleOrDefault();
        if (otherAttr == null)
        {
            Console.WriteLine($"No new attr: {newPrefix}/{attr.Name}");
            continue;
        }

        unpairedAttributes.Remove(otherAttr);
        if (attr.Value != otherAttr.Value)
            Console.WriteLine(
                $"Attr value mismatch: {newPrefix}/{attr.Name}: {attr.Value} != {otherAttr.Value}");
    }
    foreach (var attr in unpairedAttributes)
        Console.WriteLine($"No old attr: {newPrefix}/{attr.Name}");

    // 3. compare subelements
    var leftNodes = d1.Nodes().ToList();
    var rightNodes = d2.Nodes().ToList();
    var smallerCount = Math.Min(leftNodes.Count, rightNodes.Count);
    for (int i = 0; i < smallerCount; i++)
        CompareNodes(newPrefix, i, leftNodes[i], rightNodes[i]);
    if (leftNodes.Count > smallerCount)
        Console.WriteLine($"Extra {leftNodes.Count - smallerCount} nodes at old file");
    if (rightNodes.Count > smallerCount)
        Console.WriteLine($"Extra {rightNodes.Count - smallerCount} nodes at new file");
}

static void CompareNodes(string prefix, int index, XNode n1, XNode n2)
{
    if (n1.NodeType != n2.NodeType)
    {
        Console.WriteLine($"Node type mismatch: {prefix}/[{index}]");
        return;
    }

    switch (n1.NodeType)
    {
        case XmlNodeType.Element:
            CompareElements(prefix, (XElement)n1, (XElement)n2);
            break;
        case XmlNodeType.Text:
            CompareText(prefix, index, (XText)n1, (XText)n2);
            break;
    }
}

static void CompareText(string prefix, int index, XText t1, XText t2)
{
    if (t1.Value != t2.Value)
        Console.WriteLine($"Text mismatch at {prefix}[{index}]");
}

用法:

XDocument d1 = <get document #1 from somewhere>,
          d2 = <get document #2 from somewhere>;

CompareNodes("", 0, d1.Root, d2.Root);

显然,您应该写入适当的电子表格,而不是写入控制台.

Obviously, instead of writing to console you should write to the appropriate spreadsheet.

请注意,我忽略了属性重新排序而不是子节点重新排序(这似乎是正确的).

Note that I'm ignoring the attribute reorder but not subnode reorder (which seems to be right).

这篇关于检查多个 XML 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆