c# - 如何高效地逐项比较两个大的 XML 文件?

标签 c# .net xml c#-2.0 compare

我计划实现一种方法来比较两个大 XML 文件(但每个文件的元素行少于 10,000 个)。

下面的方法可行,但当文件超过100行时效果不佳。它开始得非常缓慢。我怎样才能找到更有效的解决方案。也许需要高级 C# 编程设计或更好的 C# 和 XML 处理算法。

感谢您提前发表评论。

//Remove the item which not in Event Xml and ConfAddition Xml files
XmlDocument doc = new XmlDocument();
doc.Load(xmlFile_AlarmSettingUp);

bool isNewAlid_Event = false;
bool isNewAlid_ConfAddition = false;
int alid = 0;

XmlNodeList xnList = doc.SelectNodes("/Equipment/AlarmSettingUp/EnabledALIDs/ALID");

foreach (XmlNode xn in xnList)
{                        
    XmlAttributeCollection attCol = xn.Attributes;

    for (int i = 0; i < attCol.Count; ++i)
    {
        if (attCol[i].Name == "alid")
        {
            alid = int.Parse(attCol[i].Value.ToString());
            break;
        }
    }

    //alid = int.Parse(attCol[1].Value.ToString());

    XmlDocument docEvent_Alarm = new XmlDocument();
    docEvent_Alarm.Load(xmlFile_Event);
    XmlNodeList xnListEvent_Alarm = docEvent_Alarm.SelectNodes("/Equipment/Alarms/ALID");
    foreach (XmlNode xnEvent_Alarm in xnListEvent_Alarm)
    {
        XmlAttributeCollection attColEvent_Alarm = xnEvent_Alarm.Attributes;
        int alidEvent_Alarm = int.Parse(attColEvent_Alarm[1].Value.ToString());
        if (alid == alidEvent_Alarm)
        {
            isNewAlid_Event = false;
            break;
        }
        else
        {
            isNewAlid_Event = true;
            //break;
        }
    }

    XmlDocument docConfAddition_Alarm = new XmlDocument();
    docConfAddition_Alarm.Load(xmlFile_ConfAddition);
    XmlNodeList xnListConfAddition_Alarm = docConfAddition_Alarm.SelectNodes("/Equipment/Alarms/ALID");
    foreach (XmlNode xnConfAddition_Alarm in xnListConfAddition_Alarm)
    {
        XmlAttributeCollection attColConfAddition_Alarm = xnConfAddition_Alarm.Attributes;
        int alidConfAddition_Alarm = int.Parse(attColConfAddition_Alarm[1].Value.ToString());
        if (alid == alidConfAddition_Alarm)
        {
            isNewAlid_ConfAddition = false;
            break;
        }
        else
        {
            isNewAlid_ConfAddition = true;
            //break;
        }
    }                        

    if ( isNewAlid_Event && isNewAlid_ConfAddition )
    {
        // Store the root node of the destination document into an XmlNode
        XmlNode rootDest = doc.SelectSingleNode("/Equipment/AlarmSettingUp/EnabledALIDs");
        rootDest.RemoveChild(xn);
    }

}
doc.Save(xmlFile_AlarmSettingUp);

我的 XML 文件是这样的。这两个 XML 文件的样式相同。除了有时我的应用程序可能会修改其中之一。这就是为什么我需要对它们进行修改后进行比较。

<?xml version="1.0" encoding="utf-8"?>
<Equipment xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <Licence LicenseId="" LicensePath="" />
  <!--Alarm Setting Up XML File-->
  <AlarmSettingUp>
    <EnabledALIDs>
      <ALID logicalName="Misc_EV_RM_STATION_ALREADY_RESERVED" alid="536870915" alcd="7" altx="Misc_Station  1   UnitName  2   SlotId already reserved" ceon="Misc_AlarmOn_EV_RM_STATION_ALREADY_RESERVED" ceoff="Misc_AlarmOff_EV_RM_STATION_ALREADY_RESERVED" />
      <ALID logicalName="Misc_EV_RM_SEQ_READ_ERROR" alid="536870916" alcd="7" altx="Misc_Sequence ID  1 d step  2 d read error for wafer in  3   UnitName  4   SlotId" ceon="Misc_AlarmOn_EV_RM_SEQ_READ_ERROR" ceoff="Misc_AlarmOff_EV_RM_SEQ_READ_ERROR" />
...
...
...
    </EnabledALIDs>
  </AlarmSettingUp>
</Equipment>

最佳答案

“ALID/@alid”似乎是你的关键,所以我要做的第一件事(在 foreach (XmlNode xn in xnList) 之前)是构建一个字典(假设这是唯一的)在 docEvent_Alarm.SelectNodes("/Equipment/Alarms/ALID") @alid 值上 - 那么您可以在没有 O(n*m) 性能的情况下完成大部分工作 - 它将更加 O( n+m)(这是一个很大的区别)。

var lookup = new Dictionary<string, XmlElement>();
foreach(XmlElement el in docEvent_Alarm.SelectNodes("/Equipment/Alarms/ALID")) {
    lookup.Add(el.GetAttribute("alid"), el);
}

然后你可以使用:

XmlElement other;
if(lookup.TryGetValue(otherKey, out other)) {
   // exists; element now in "other"
} else {
   // doesn't exist
}

关于c# - 如何高效地逐项比较两个大的 XML 文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4333625/

相关文章:

c# - 数学表达式生成最好不使用堆栈或队列

c# - C# 中动态对象的转换是如何工作的

c# - 为什么 List<> 实现 IList

c# - 在单独的项目与单独的命名空间中组织代码

objective-c - 在 iOS 中从文本文件创建对象的最有效方法

java - 在 java 中,如何在第 3 方工具返回的 DOM 中创建自己的 xml 子类元素

android - XML-安卓 :layout_above Error

c# - InvalidOperationException 错误反射(reflect)类

c# - NHibernate、Oracle 和 sql 工具

c# - Dispatcher.BeginInvoke c#,silverlight