2008-10-03 34 views
52

कुछ व्यापक इकाई परीक्षण के लिए बेस क्लास के हिस्से के रूप में, मैं एक सहायक फ़ंक्शन लिख रहा हूं जो एक XmlDocument ऑब्जेक्ट के नोड्स को सी # (.NET) में दूसरे से तुलना करता है। इनमें से कुछ आवश्यकताओं:आप दो एक्सएमएल दस्तावेज़ों की तुलना कैसे करेंगे?

  • पहला दस्तावेज स्रोत, उदा है मैं एक्सएमएल दस्तावेज़ की तरह दिखना चाहता हूं। इस प्रकार दूसरा वह है जिसमें मैं अंतर ढूंढना चाहता हूं और इसमें पहले दस्तावेज़ में अतिरिक्त नोड्स शामिल नहीं होना चाहिए।
  • एक अपवाद फेंकना चाहिए जब बहुत से महत्वपूर्ण मतभेद पाए जाते हैं, और इसे विवरण में मानव चमक से आसानी से समझा जाना चाहिए।
  • बाल तत्व आदेश महत्वपूर्ण है, गुण किसी भी क्रम में हो सकते हैं।
  • कुछ विशेषताएं अनजान हैं; विशेष रूप से xsi:schemaLocation और xmlns:xsi, हालांकि मैं कौन से पास में सक्षम होना चाहता हूं।
  • नामस्थानों के लिए उपसर्ग दोनों विशेषताओं और तत्वों में मेल खाना चाहिए।
  • तत्वों के बीच व्हाइटस्पेस अप्रासंगिक है।
  • तत्व या तो में बच्चे तत्व याInnerText हैं, लेकिन दोनों नहीं।

जबकि मैं एक साथ कुछ छीन रहा हूं: क्या किसी ने भी ऐसा कोड लिखा है और क्या इसे यहां साझा करना संभव होगा?

एक तरफ, आप पहले और दूसरे दस्तावेज़ों को क्या कहेंगे? मैं उन्हें "स्रोत" और "लक्ष्य" के रूप में संदर्भित कर रहा हूं, लेकिन स्रोत के बाद से यह गलत लगता है कि मैं लक्ष्य जैसा दिखाना चाहता हूं, अन्यथा मैंने अपवाद फेंक दिया है।

+0

नोड्स एक ही हो सकता है लेकिन एक अलग क्रम में घोषित किया जाना? – alexmac

+0

नहीं, नोड्स एक ही क्रम में होना चाहिए। दस्तावेजों की आवश्यकता होने के अलावा, यह थोड़ा सा सरल बना देता है (केवल बच्चों को गिनती है और एक-एक करके जांचें)। –

+0

> विशेषताएँ किसी भी क्रम में अच्छी बात हो सकती हैं, क्योंकि विशेषता परिभाषा द्वारा अनियंत्रित होती है। –

उत्तर

51

माइक्रोसॉफ्ट एक XML diff API कि आप

+1

यह बहुत अच्छा है! दुर्भाग्य से एक चीज जो नहीं करती है वह मुझे कुछ विशेषताओं को अनदेखा करने की अनुमति देती है। –

+0

मैं अपनी पोस्ट में उल्लेख करना भूल गया, एक्सएसएलटी में किए गए अन्य कार्यों में से एक को कुछ विशेषताओं को फ़िल्टर करना था। – runrig

+0

टूल के लिए एक और लिंक यहां है http://msdn.microsoft.com/en-gb/library/aa302294.aspx –

4

तुलना एक्सएमएल दस्तावेजों का उपयोग कर सकते जटिल है। कुछ टूल के लिए Google xmldiff (यहां तक ​​कि माइक्रोसॉफ्ट समाधान भी है) के लिए Google। मैंने इसे दो तरीकों से हल कर लिया है। मैंने तत्वों और विशेषताओं को क्रमबद्ध करने के लिए एक्सएसएलटी का उपयोग किया (क्योंकि कभी-कभी वे एक अलग क्रम में दिखाई देंगे, और मुझे इसकी परवाह नहीं है), और उन गुणों को फ़िल्टर करें जिन्हें मैं तुलना नहीं करना चाहता था, और फिर या तो XML::Diff या XML::SemanticDiff perl का उपयोग किया गया मॉड्यूल, या प्रत्येक तत्व के साथ प्रत्येक दस्तावेज़ और प्रत्येक पंक्ति के साथ सुंदर मुद्रित, और परिणामों पर यूनिक्स कमांड लाइन diff का उपयोग कर।

3

मैं XML फ़ाइलों की तुलना करने के लिए ExamXML का उपयोग कर रहा हूं। आप इसे आज़मा सकते हैं। लेखकों, A7Soft, यह भी एपीआई एक्सएमएल फाइल

4

एक और तरीका यह हो सकता है ऐसा करने के लिए की तुलना के लिए प्रदान करते हैं -

  1. दो अलग तार में दोनों फ़ाइलों की सामग्री को प्राप्त करें।
  2. एक एक्सएसएलटी का उपयोग कर स्ट्रिंग्स को ट्रांसफॉर्म करें (जो बस सबकुछ दो नए स्ट्रिंग्स पर कॉपी करेगा)। यह सुनिश्चित करेगा कि तत्वों के बाहर सभी रिक्त स्थान हटा दिए जाएंगे। इसके परिणामस्वरूप यह दो नए तार होंगे।
  3. अब, बस एक दूसरे के साथ दो तारों की तुलना करें।

यह आपको अंतर का सही स्थान नहीं देगा, लेकिन यदि आप सिर्फ यह जानना चाहते हैं कि कोई अंतर है, तो किसी तीसरे पक्ष के पुस्तकालयों के बिना करना आसान है।

+1

-1: यह प्रश्न का उत्तर नहीं देता है। –

+2

यह विशेष प्रश्न का उत्तर नहीं देता है, लेकिन अवधारणा प्रश्न में उठाई गई समस्या से प्रासंगिक है। मेरा +1 – yegor256

5

XMLUnit आज़माएं। यह लाइब्रेरी जावा और .NET

2

ओपी के लिए प्रासंगिक नहीं है क्योंकि यह वर्तमान में बाल आदेश को अनदेखा करता है, लेकिन यदि आप केवल कोड समाधान चाहते हैं तो आप XmlSpecificationCompare को आजमा सकते हैं, जिसे मैं somewhat misguidedly विकसित करता हूं।

5
4

यह कोड आपके सभी आवश्यकताओं को पूरा नहीं है, लेकिन यह आसान है और मैं अपने इकाई परीक्षण के लिए उपयोग कर रहा हूँ। विशेषता आदेश कोई फर्क नहीं पड़ता, लेकिन तत्व आदेश करता है। तत्व आंतरिक पाठ की तुलना नहीं की जाती है। गुणों की तुलना करते समय मैंने मामले को भी नजरअंदाज कर दिया, लेकिन आप इसे आसानी से हटा सकते हैं।

public bool XMLCompare(XElement primary, XElement secondary) 
{ 
    if (primary.HasAttributes) { 
     if (primary.Attributes.Count != secondary.Attributes.Count) 
      return false; 
     foreach (XAttribute attr in primary.Attributes) { 
      if (secondary.Attribute(attr.Name.LocalName) == null) 
       return false; 
      if (attr.Value.ToLower != secondary.Attribute(attr.Name.LocalName).Value.ToLower) 
       return false; 
     } 
    } 
    if (primary.HasElements) { 
     if (primary.Elements.Count != secondary.Elements.Count) 
      return false; 
     for (i = 0; i <= primary.Elements.Count - 1; i++) { 
      if (XMLCompare(primary.Nodes(i), secondary.Nodes(i)) == false) 
       return false; 
     } 
    } 
    return true; 
} 
3

https://github.com/CameronWills/FatAntelope Microsoft XML Diff एपीआई के एक अन्य विकल्प पुस्तकालय। इसमें एक एक्सएमएल diffing एल्गोरिदम है जो दो एक्सएमएल दस्तावेजों की एक अनियमित तुलना करने और एक इष्टतम मिलान का उत्पादन करने के लिए है। http://pages.cs.wisc.edu/~yuanwang/xdiff.html

अस्वीकरण:

यह यहाँ वर्णित एक्स Diff एल्गोरिथ्म के एक सी # बंदरगाह है मैं इसे :) लिखा

0

आधार @Two Cents का जवाब और इस लिंक XMLSorting मैं बनाया है का उपयोग करते हुए मेरे अपने XmlComparer

तुलना करें एक्सएमएल कार्यक्रम

private static bool compareXML(XmlNode node, XmlNode comparenode) 
    { 

     if (node.Value != comparenode.Value) 
      return false; 

      if (node.Attributes.Count>0) 
      { 
       foreach (XmlAttribute parentnodeattribute in node.Attributes) 
       { 
        string parentattributename = parentnodeattribute.Name; 
        string parentattributevalue = parentnodeattribute.Value; 
        if (parentattributevalue != comparenode.Attributes[parentattributename].Value) 
        { 
         return false; 
        } 

       } 

      } 

      if(node.HasChildNodes) 
      { 
      sortXML(comparenode); 
      if (node.ChildNodes.Count != comparenode.ChildNodes.Count) 
       return false; 
      for(int i=0; i<node.ChildNodes.Count;i++) 
       { 

       string name = node.ChildNodes[i].LocalName; 
       if (compareXML(node.ChildNodes[i], comparenode.ChildNodes[i]) == false) 
        return false; 
       } 

      } 



     return true; 
    } 

क्रमबद्ध एक्सएमएल कार्यक्रम

private static void sortXML(XmlNode documentElement) 
    { 
     int i = 1; 
     SortAttributes(documentElement.Attributes); 
     SortElements(documentElement); 
     foreach (XmlNode childNode in documentElement.ChildNodes) 
     { 
      sortXML(childNode); 

     } 
    } 



    private static void SortElements(XmlNode rootNode) 
    { 



      for(int j = 0; j < rootNode.ChildNodes.Count; j++) { 
       for (int i = 1; i < rootNode.ChildNodes.Count; i++) 
       { 
        if (String.Compare(rootNode.ChildNodes[i].Name, rootNode.ChildNodes[1 - 1].Name) < 0) 
        { 
         rootNode.InsertBefore(rootNode.ChildNodes[i], rootNode.ChildNodes[i - 1]); 

        } 


       } 
      } 
      // Console.WriteLine(j++); 


    } 
private static void SortAttributes(XmlAttributeCollection attribCol) 
    { 
     if (attribCol == null) 
      return; 
     bool changed = true; 
     while (changed) 
     { 
      changed = false; 
      for (int i = 1; i < attribCol.Count; i++) 
     { 
       if (String.Compare(attribCol[i].Name, attribCol[i - 1].Name) < 0) 
       { 
        //Replace 
        attribCol.InsertBefore(attribCol[i], attribCol[i - 1]); 
        changed = true; 

       } 
      } 
     } 
    } 
+0

एक्सएसएलटी एक्सएमएल को सॉर्ट करने का एक तेज़ तरीका होगा। साथ ही, लूप में सॉर्ट का उपयोग करने के बजाए दोनों दस्तावेज़ों को सॉर्ट क्यों न करें? –

+0

@PankajJaju मुझे पता है कि xslt तेज़ है, लेकिन मुझे xslt प्रोग्रामिंग का कोई ज्ञान नहीं है, मैं भी दोनों दस्तावेज़ों को सॉर्ट कर रहा हूं, मैं दोनों दस्तावेज़ों के रूट तत्व को तुलनात्मक रूप से तुलना कर रहा हूं जैसे XMLX 'comparXML (document1। रूटनोड, document2.rootnode); 'और दोनों दस्तावेज़ों के प्रत्येक नोड को सॉर्ट करना –