简体   繁体   中英

Help with XmlDiffPatch, Navigating XML doc by number of nodes?

I'm trying for the first time to use XmlDiffPatch and not getting anywhere fast!

What I want to do is "just" compare the infoset of two XML files and list the differences and the XPath to the changes in a file that's it!

After much googling I found the code below which works well as far as it goes, it does the compare and find the changes and creates the file below but how do i get the xpaths from this?

I have just found this: "The xd:node element contains the match attribute with a path descriptor identifying the referenced node.

Here is an example of what this element may look like:

<xd:node match="4"/>

Here is an example of xd:node element that is used to identify the fourth node of the current source element. The changes on the child nodes of the fourth node are described in the child nodes of the xd:node element.

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

So how do you move around an XML doc by counting the number of nodes!??

Output file 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 thus far:

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);
}

Take a look in this recursive function. Reference: 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;
            }
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM