2011-01-13 2 views
1

Ich versuche zum ersten Mal XmlDiffPatch zu verwenden und nicht schnell irgendwo zu bekommen!Hilfe mit XmlDiffPatch, Navigieren XML doc nach Anzahl der Knoten?

Was ich tun möchte, ist "nur" vergleichen Sie das Infoset von zwei XML-Dateien und listet die Unterschiede und den XPath auf die Änderungen in einer Datei, das ist es!

Nach viel Googeln fand ich den Code unten, der funktioniert so gut wie es geht, es macht den Vergleich und finden Sie die Änderungen und erstellt die Datei unten, aber wie bekomme ich die XPaths davon?

Ich habe gefunden, nur dies: „Der xd: Knotenelement enthält, das Spiel Attribut mit einem Pfaddescriptors die referenzierte Knoten identifizieren

Hier ist ein Beispiel dafür, was dieses Element aussehen könnte.

<xd:node match="4"/> 

Hier ist ein Beispiel für das Element xd: node, das zur Identifizierung des vierten Knotens des aktuellen Quellelements verwendet wird Die Änderungen an den untergeordneten Knoten des vierten Knotens werden in den untergeordneten Knoten des Elements xd: node beschrieben

<xd:node match="4"> 
    <xd:change match="1">Changed text</change> 
    <xd:remove match="2" /> 
</xd:node> 

Also, wie bewegen Sie sich um ein XML-Dokument, indem Sie die Anzahl der Knoten zählen!

Ausgabedatei vxd.out:

<?xml version="1.0" encoding="utf-8"?> 
<xd:xmldiff version="1.0" srcDocHash="4711104825377024894" options="None" fragments="no" xmlns:xd="http://schemas.microsoft.com/xmltools/2002/xmldiff"> 
    <xd:node match="2"> 
    <xd:node match="1"> 
     <xd:node match="2"> 
     <xd:node match="4"> 
      <xd:change match="1">TESTING</xd:change> 
     </xd:node> 
     </xd:node> 
     <xd:node match="4"> 
     <xd:node match="5"> 
      <xd:change match="1">A1</xd:change> 
     </xd:node> 
     </xd:node> 
    </xd:node> 
    </xd:node> 
</xd:xmldiff> 

-Code so weit:

public void DoCompare(string file1, string file2) 
{ 
    Random r = new Random(); 

    string startupPath = Application.StartupPath; 
    //output diff file. 
    diffFile = startupPath + Path.DirectorySeparatorChar + "vxd.out"; 
    XmlTextWriter tw = new XmlTextWriter(new StreamWriter(diffFile)); 
    tw.Formatting = Formatting.Indented; 

    bool isEqual = false; 

    //Now compare the two files. 
    try 
    { 
     isEqual = diff.Compare(file1, file2, compareFragments, tw); 
    } 
    catch (XmlException xe) 
    { 
     MessageBox.Show("An exception occured while comparing\n" + xe.StackTrace); 
    } 
    finally 
    { 
     tw.Close(); 
    } 

    if (isEqual) 
    { 
     //This means the files were identical for given options. 
     MessageBox.Show("Files Identical for the given options"); 
     return; //dont need to show the differences. 
    } 

    //Files were not equal, so construct XmlDiffView. 
    XmlDiffView dv = new XmlDiffView(); 
    //Load the original file again and the diff file. 
    XmlTextReader orig = new XmlTextReader(file1); 
    XmlTextReader diffGram = new XmlTextReader(diffFile); 
    dv.Load(orig, diffGram); 
} 

Antwort

1

einen Blick in dieser rekursiven Funktion übernehmen. Referenz: http://msdn.microsoft.com/en-us/library/aa302295.aspx

private void ApplyDiffgram(XmlNode diffgramParent, XmlDiffViewParentNode sourceParent) 
{ 
    sourceParent.CreateSourceNodesIndex(); 
    XmlDiffViewNode currentPosition = null; 

    IEnumerator diffgramChildren=diffgramParent.ChildNodes.GetEnumerator(); 
     while (diffgramChildren.MoveNext()) 
     { 
      XmlNode diffgramNode = (XmlNode)diffgramChildren.Current; 
      if (diffgramNode.NodeType == XmlNodeType.Comment) 
       continue; 

      XmlElement diffgramElement = diffgramChildren.Current as XmlElement; 

      if (diffgramElement == null) 
       throw new Exception("Invalid node in diffgram."); 

      if (diffgramElement.NamespaceURI != XmlDiff.NamespaceUri) 
       throw new Exception("Invalid element in diffgram."); 

      string matchAttr = diffgramElement.GetAttribute("match"); 
      XmlDiffPathNodeList matchNodes = null; 
      if (matchAttr != string.Empty) 
      matchNodes = XmlDiffPath.SelectNodes(_doc, sourceParent, matchAttr); 

      switch (diffgramElement.LocalName) { 
       case "node": 
        if (matchNodes.Count != 1) 
         throw new Exception("The 'match' attribute of 'node' element must select a single node."); 
        matchNodes.MoveNext(); 
        if (diffgramElement.ChildNodes.Count > 0) 
         ApplyDiffgram(diffgramElement, (XmlDiffViewParentNode)matchNodes.Current); 
        currentPosition = matchNodes.Current; 
        break; 
       case "add": 
        if (matchAttr != string.Empty) { 
         OnAddMatch(diffgramElement, matchNodes, sourceParent, ref currentPosition); 
        } 
        else { 
         string typeAttr = diffgramElement.GetAttribute("type"); 
         if (typeAttr != string.Empty) { 
          OnAddNode(diffgramElement, typeAttr, sourceParent, ref currentPosition); 
         } 
         else { 
          OnAddFragment(diffgramElement, sourceParent, ref currentPosition); 
         } 
        } 
        break; 
       case "remove": 
        OnRemove(diffgramElement, matchNodes, sourceParent, ref currentPosition); 
        break; 
       case "change": 
        OnChange(diffgramElement, matchNodes, sourceParent, ref currentPosition); 
        break; 
      } 
     } 
    }