2010-12-02 5 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

성능을 벤치 마크 할 때 중첩 된 반복은 사용할 수 없습니다. 코드 정리. –

답변

1

는 "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 
} 
+0

'var' .net 2.0에서 제공됩니까? NET 2.0을 기반으로해야합니다. –

+1

@Nano HE,이 경우 var를 단순히 'Dictionary '형식 이름으로 바꿉니다. – steinar

+1

@Nano -'var'은 C# 3.0으로 모든 .NET 버전을 대상으로 사용할 수 있습니다. 그러나 @steiner는 옳다; C# 2.0 (VS2005)을 사용하는 경우'Dictionary ' –

1

을 XmlDocument 및 관련 클래스 (있는 XmlNode, ...) XML 처리에 꽤 빨리되지 않습니다. XmlTextReader를 대신 사용해보십시오.

또한 부모 루프의 반복마다 docEvent_Alarm.Load(xmlFile_Event);docConfAddition_Alarm.Load(xmlFile_ConfAddition);이라고 부릅니다. 좋지 않습니다. xmlFile_EventxmlFile_ConfAddition이 모든 처리 중에 지속되는 경우 주 루프보다 먼저 초기화하는 것이 좋습니다.

관련 문제