XML比较器C#

时间:2011-09-16 10:57:29

标签: c# xml algorithm

我想比较2个XML文件。 如果两者具有相同的结构,看起来很容易。但不是在我的情况下:( 我的文件看起来像:

<root>
 <t>
  <child1>
    <cc1>val</cc1>
    <cc2>val</cc2>
     ......
  </child1>
  <child2>
    <cc1>val</cc1>
    <cc2>val</cc2>
     ......
  </child2>
  <child2>
    <cc1>val</cc1>
    <cc2>val</cc2>
     ......
  </child2>
    .......
  <child3>
    <cc1>val</cc1>
    <cc2>val</cc2>
     ......
  </child3>
   ....
 </t>
 <t>
   ...
 </t>
 .....
</root>

他们可以拥有任何数量的儿童和儿童...... 任务是

  1. 仅比较一个已定义的块。我需要搜索第一个孩子的孩子的价值(本例中为child1.cc1.value)

  2. 在比较期间,可以跳过一些节点(跳过的节点的名称存储在某处,例如,在字符串数组中)

  3. 可以有多个相同的节点,如。如果不忽略child2,那么我需要确保它们的数量相同,并且它们都与相应的第二个文件一致。所以可能存在下一种情况:

  4. 第一个文件包含:

     <child2><cc1>1</cc1>...</child2>
     <child2><cc1>3</cc1>...</child2>
     <child2><cc1>2</cc1>...</child2>
    

    第2个文件包含:

     <child2><cc1>2</cc1>...</child2>
     <child2><cc1>1</cc1>...</child2>
     <child2><cc1>3</cc1>...</child2>
    

    这意味着它们彼此对应。 所以他们可能是随机顺序。

    现在我无法决定如何实现这个算法。我建议使用DataSet对象,但这种XML结构对于简单地使用DataTables,dataRows等来说太难了。

    现在我正在尝试XmlNodes。但我还没有意识到那个部分,我有几个相同的节点,随机顺序不同的数据。

    有什么想法吗?

1 个答案:

答案 0 :(得分:2)

您的XML文件有多大?现实中的结构有多复杂?

如果不是太大或太复杂,我建议将整个文件解析为类结构,然后对类的属性执行验证。例如(伪代码)......

xmlClass file1 = new xmlClass(file1info);
xmlClass file2 = new xmlClass(file2info);

//Custom classes have now parsed XML files in whichever way you like

if (file1.numberOfChildren != file2.numberOfChildren) 
{
  //comparison fail
} 
elseif (!file1.orderOfChildrenSame(file2))
{
  //comparison fail
}
else
{
  //comparison success
}

显然,xmlClass的方法和属性的确切实施将取决于您的具体要求。

XmlClass可能是粗略布局......

using System;
using System.Collections.Generic;
using System.Xml;

public class XmlClass
{ 
    private XmlDocument _xmlDoc;
    private List<ChildClass> _children As New List<ChildClass>();

    public XmlClass(FileInfo fil){
        _xmlDoc = New XmlDocument();
        _xmlDoc.Load(fil.FullName);

        ParseChildren();

        _xmlDoc = Nothing;
    }

    private void ParseChildren(){
        XmlNodeList ndl = _xmlDoc.SelectNodes("/root/t") //select all <t>s
        foreach (xmlNode nodT in ndl.Nodes){
            foreach (xmlNode nodChild in nodT.ChildNodes()){
                _children.Add(new ChildClass(nodChild));
            }
        }
        // Now _children contains all child nodes of <t>s and can be worked with logically
    }

    public int numberOfChildren
    {
        get {return _children.Count();}
    }
}

您显然需要实现ChildClass - 这可能反过来包含ChildClass本身的集合(允许您描述的层次结构)。您还需要根据需要实施其他验证方法。此外,您可能需要实现其他类来表示您感兴趣的文档中的其他节点类型。

请勿解析超出您需要的内容以进行验证! - 这取决于你的最终目标。

<强> PS

我还建议这种XML格式在<child1><child2>设置方面不是很“好”。拥有<child id="1"><child id="2">等会更加XMLesque。因为大概<child1><child2>基本上是节点的类型