2010-12-02 8 views
2

私は2つの大きなXMLファイルを比較する方法を実装するつもりです。アイテムごとに2つの大きな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ファイルはこれです。 2つのXMLファイルは同じスタイルです。一部の時間を除いて、それらのうちの1つは私のアプリケーションによって修正されるかもしれません。だからこそ私はそれらを比較する必要があります。

<?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がすべての処理中に永続的な場合は、メインループの前に初期化することをお勧めします。

関連する問題