2010-12-02 16 views
2

Я планирую реализовать метод сравнения двух больших XML-файлов (но менее 10 000 строк элементов для каждого другого).Как эффективно сравнить два больших XML-файла?

Метод ниже работает, но это не очень хорошо, если файл содержит более 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> 
+1

Уг, вложенные итерации - это не путь, когда вы пытаетесь сравнить производительность. Очистите свой код. – 2010-12-02 10:02:41

ответ

1

«Алид/@ Алид», кажется, ключ, так что первое, что я хотел бы сделать (до 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 
} 
+0

`var` Поставляется от .net 2.0? Я должен основываться на .net 2.0. – 2010-12-02 10:04:53

1

XmlDocument и связанные с ним классы (XMLnode, ...) не очень быстро при обработке XML. Вместо этого попробуйте XmlTextReader.

Также вы вызываете docEvent_Alarm.Load(xmlFile_Event); и docConfAddition_Alarm.Load(xmlFile_ConfAddition); каждую итерацию родительского цикла - это нехорошо. Если ваши xmlFile_Event и xmlFile_ConfAddition являются постоянными во время всей обработки - лучше инициализировать его перед основным контуром.