2012-05-07 15 views
5

मेरे पास धारावाहिक वस्तुओं से भरा ऑडिट सूची है, और मैं उनकी तुलना करना चाहता हूं और मतभेदों की एक सूची वापस कराना चाहता हूं। 'तुलना' से मेरा मतलब है कि मैं वापस लौटना चाहता हूं जहां तत्व के लिए पाठ बदल गया है, या जहां नोड जोड़ा गया है (इसलिए यह एक्सएमएल 1 में नहीं है, लेकिन यह एक्सएमएल 2 में है- यह दूसरी तरफ नहीं होगा)एक्सएमएल टुकड़ों की तुलना करें और अंतरों को वापस करें

नमूना xml:

<HotelBookingView xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Id>119</Id> 
    <RoomId>1</RoomId> 
    <ChangeRequested>false</ChangeRequested> 
    <CourseBookings>  
    <CourseHotelLink> 
     <Id>0</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView> 

नामस्थान और नाम/टैग के मामले परिवर्तन नहीं होगा। इस नमूने में जो कुछ भी बदल सकता है वह टैग के बीच मूल्य है, और 'कोर्सहोटललिंक की संख्या (इसकी एक क्रमबद्ध सूची) है।

अंतिम परिणाम जो मैं चाहता हूं वह एक नोड बदल गया है- पुराना मूल्य और नया मान।

उनकी तुलना करने का सबसे अच्छा विकल्प क्या है? मैं .NET 4.0 का उपयोग कर रहा हूं इसलिए linq एक विकल्प है। मुझे सभी नोड्स के नामों को जानने के बिना तुलना करने में सक्षम होना चाहिए- हालांकि मैं कभी भी उसी प्रकार की दो वस्तुओं की तुलना करूंगा। मैं निम्नलिखित कोड का उपयोग करने की कोशिश कर रहा हूं, लेकिन मैं टेक्स्ट और साथ ही अतिरिक्त नोड्स में बदलावों को चुनने के लिए अनुकूलित करने का प्रबंधन नहीं कर सकता।

XmlDocument Xml1 = new XmlDocument(); 
XmlDocument Xml2 = new XmlDocument(); 
Xml1.LoadXml(list[1].Changes); 
Xml2.LoadXml(list[2].Changes); 
foreach (XmlNode chNode in Xml2.ChildNodes) 
{ 
    CompareLower(chNode); 
} 

protected void CompareLower(XmlNode aNode) 
{ 
    foreach (XmlNode chlNode in aNode.ChildNodes) 
    { 
     string Path = CreatePath(chlNode); 
     if (chlNode.Name == "#text") 
     { 
      //all my efforts at comparing text have failed 
      continue; 
     } 
     if (Xml1.SelectNodes(Path).Count == 0) 
     { 
      XmlNode TempNode = Xml1.ImportNode(chlNode, true); 
      //node didn't used to exist, this works- though doesn't return values 
      str = str + "New Node: " + TempNode.Name + ": " + TempNode.Value; 
     } 
     else 
     { 
      CompareLower(chlNode); 
     } 
    } 
} 

इसकी संभावना मेरे कोड का प्रयास मील दूर कर रहे हैं और वहाँ ऐसा करने के लिए एक बहुत अच्छा तरीका है, किसी भी सुझाव का स्वागत करते हैं!

जोड़ने के लिए संपादित: मैं एमएस एक्सएमएल डिफ टूल का उपयोग करके समाप्त हुआ, निम्न कोड दो एक्सएमएल नोड्स की एक बड़ी HTML तालिका सूची बनाता है, जिसमें हरे रंग में अंतर दिखाई देते हैं। तो एचटीएमएल का उत्पादन करने के लिए यह संभव है (हालांकि पागल), फिर टेक्स्ट 'लाइटग्रीन' (हाइलाइट किए गए मान) को खोजने के लिए इसके माध्यम से सॉर्ट करें, फिर केवल बदले गए बच्चे-नोड को प्रदर्शित करने के लिए कुछ स्ट्रिंग संरचनाएं करें।

var node1 = XElement.Parse("Xml string 1 here").CreateReader(); 
var node2 = XElement.Parse("Xml string 2 here").CreateReader(); 

MemoryStream diffgram = new MemoryStream(); 
XmlTextWriter diffgramWriter = new XmlTextWriter(new StreamWriter(diffgram)); 

XmlDiff xmlDiff = new XmlDiff(XmlDiffOptions.IgnoreChildOrder); 
xmlDiff.Algorithm = XmlDiffAlgorithm.Fast; 
xmlDiff.Compare(node1, node2,diffgramWriter); 

diffgram.Seek(0, SeekOrigin.Begin); 
XmlDiffView xmlDiffView = new Microsoft.XmlDiffPatch.XmlDiffView(); 
StringBuilder sb = new StringBuilder(); 
TextWriter resultHtml = new StringWriter(sb); 
xmlDiffView.Load("Xml string 1", new XmlTextReader(diffgram)); 

xmlDiffView.GetHtml(resultHtml); 
resultHtml.Close(); 
+1

इस पोस्ट पर एक नज़र डालें:

var diff = new Microsoft.XmlDiffPatch.XmlDiff(); diff.Compare(node1, node2, writer); writer.Flush(); writer.Close(); 

result अब एक XDocument कि मतभेदों की एक सारांश है http://stackoverflow.com/प्रश्न/167946/कैसे-आप-तुलना-दो-xml-दस्तावेज़ –

+0

मैंने अभी तक काम नहीं किया है कि एमएस डिफ और पैच को XML स्ट्रिंग्स लेने के लिए कैसे प्राप्त करें- मेरा एक्सएमएल डेटाबेस से आता है और मैं नहीं चाहता जब भी मैं टी चाहता हूं फ़ाइलों को बनाने के लिए ओ इसका इस्तेमाल करें ... बस मुझे घना होना चाहिए। – UglyTeapot

+0

आपको फ़ाइलों को बनाने की आवश्यकता नहीं है, यह फ़ाइलों की तुलना करने के लिए कई ओवरलोड के साथ आता है, XmlTextReader या XmlNode –

उत्तर

7

XMlDiff का उपयोग करने का तरीका है - यह साबित करने के लिए कि यह कुछ कामकाजी कोड है। मैं आपके एक्सएमएल का उपयोग कर रहा हूँ। यदि एक्सएमएल अलग है (या अमान्य), यह काम नहीं कर सकता है।

मूल:

var xml1 = @"<HotelBookingView xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
<Id>119</Id> 
<RoomId>1</RoomId> 
<ChangeRequested>false</ChangeRequested> 
<CourseBookings>  
    <CourseHotelLink> 
    <Id>0</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView>"; 

CourseBookings में विभिन्न Id मूल्य:

var xml2 = @"<HotelBookingView xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema""> 
<Id>119</Id> 
<RoomId>1</RoomId> 
<ChangeRequested>false</ChangeRequested> 
<CourseBookings>  
    <CourseHotelLink> 
    <Id>1</Id> 
    </CourseHotelLink> 
</CourseBookings> 
</HotelBookingView>"; 

पाठकों बनाने (यदि आवश्यक XDocument को बदलना) के कम प्रयास तरीका:

var node1 = XElement.Parse(xml1).CreateReader(); 
var node2 = XElement.Parse(xml2).CreateReader(); 

परिणाम तैयार लेखक:

var result = new XDocument(); 
var writer = result.CreateWriter(); 

diff कार्य करें:

<xd:xmldiff version="1.0" srcDocHash="14506386314386767543" options="None" fragments="no" xmlns:xd="http://schemas.microsoft.com/xmltools/2002/xmldiff"> 
    <xd:node match="1"> 
    <xd:node match="4"> 
     <xd:node match="1"> 
     <xd:node match="1"> 
      <xd:change match="1">1</xd:change> 
     </xd:node> 
     </xd:node> 
    </xd:node> 
    </xd:node> 
</xd:xmldiff> 
+0

यह काम करता है, धन्यवाद! तो मुझे बस 'कोर्सबुकिंग आईडी 0, अब 1' जैसी चीज़ों को प्रदर्शित करने में सक्षम होने के लिए diffgram को पार्स करने की आवश्यकता है, जो मजेदार होना चाहिए! – UglyTeapot

+0

यह स्वीकार करने के लिए मत भूलना कि क्या यह मूल प्रश्न का उत्तर देता है :-) 'xmldiff' से वापसी की व्याख्या करने के बारे में बहुत सारी जानकारी है। – yamen

+0

स्वीकृत, धन्यवाद! और .. केवल मतभेद दिखाने के लिए diffgrams की व्याख्या करने के उदाहरण हैं? मेरा कमजोर google-fu कुछ भी नहीं ढूंढ रहा है – UglyTeapot

संबंधित मुद्दे