帮助XmlDiffPatch,按节点数导航XML文档?

时间:2011-01-13 19:18:46

标签: c# .net xml

我第一次尝试使用XmlDiffPatch并且没有快速到达任何地方!

我想要做的是“只是”比较两个XML文件的信息集并列出差异,并将XPath列入文件中的更改!

经过大量的谷歌搜索后,我发现下面的代码效果很好,它会进行比较并找到更改并在下面创建文件但是如何从中获取xpath?

我刚刚发现了这个: “xd:node元素包含match属性,其中包含标识引用节点的路径描述符。

以下是此元素的示例:

<xd:node match="4"/>

以下是xd:node元素的示例,用于标识当前源元素的第四个节点。第四个节点的子节点上的更改在xd:node元素的子节点中描述。

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

那么如何通过计算节点数量来移动XML文档呢???

输出文件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>

到目前为止的代码:

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

1 个答案:

答案 0 :(得分:1)

看看这个递归函数。 参考: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;
            }
        }
    }