简体   繁体   English

通过C#中的节点或属性值比较Xml

[英]Comparing Xml by values of nodes or attributes in C#

I want to compare two (or more) XMLs files by values of nodes or attributes. 我想通过节点或属性的值比较两个(或多个)XML文件。 I am not interested by node names or attributes. 我对节点名称或属性不感兴趣。

Searching on google i found XMLDiff Patch ( http://msdn.microsoft.com/en-us/library/aa302294.aspx ), but it not work for me.. or i don`t know how to make settings to work for me. 在Google上搜索时,我发现了XMLDiff补丁( http://msdn.microsoft.com/zh-cn/library/aa302294.aspx ),但它对我不起作用..或者我不知道如何进行设置才能使用我。

FileA 文件A

  <Root odata.context="http://services.odata.org/V4/(S(i53ojihzxawmvtyyvztbaelk))/TripPinServiceRW/$metadata">
  <value>
    <name>Photos</name>
    <kind>EntitySet</kind>
    <url>Photos</url>
  </value>
  <value>
    <name>People</name>
    <kind>EntitySet</kind>
    <url>People</url>
  </value>
  <value>
    <name>Airlines</name>
    <kind>EntitySet</kind>
    <url>Airlines</url>
  </value>
  <value>
    <name>Airports</name>
    <kind>EntitySet</kind>
    <url>Airports</url>
  </value>
  <value>
    <name>Me</name>
    <kind>Singleton</kind>
    <url>Me</url>
  </value>
  <value>
    <name>GetNearestAirport</name>
    <kind>FunctionImport</kind>
    <url>GetNearestAirport</url>
  </value>
</Root>

File B 文件B

<Root odata.context="http://services.odata.org/V4/(S(i53ojihzxawmvtyyvztbaelk))/TripPinServiceRW/$metadata">
  <value>
    <name>Photos</name>
    <kind>EntitySet</kind>
    <url>Photos</url>
  </value>
  <value>
    <name>People</name>
    <kind>EntitySet</kind>
    <url>People</url>
  </value>
  <value>
    <name>Airlines</name>
    <kind>EntitySet</kind>
    <url>Airlines</url>
  </value>
  <value>
    <name>Airports</name>
    <kind>EntitySet</kind>
    <url>Airports</url>
  </value>
  <value>
    <name>Me</name>
    <kind>Singleton</kind>
    <url>Me</url>
  </value>
  <value>
    <name>GetNearestAirport</name>
    <kind>FunctionImport</kind>
    <url>GetNearestAirport</url>
  </value>
</Root>

I want to validate values of each nodes or attributes. 我想验证每个节点或属性的值。 Thanks! 谢谢!

If you want to do it your self and the structure of the xml documents is known and constant you could maybe do something like this (supposing that xdocB is the valid document): 如果您想自己做,并且xml文档的结构是已知且恒定的,则可以执行以下操作(假设xdocB是有效的文档):

class NodeComparer : IEqualityComparer<XmlNode>
{
  public bool Equals(XmlNode x, XmlNode y)
  {
    if (x == null || y == null)
      return false;

    if (x.ChildNodes.Count != y.ChildNodes.Count)
      return false;

    var nodeNames = new [] { "name", "kind", "url" };

    for (int i = 0; i < x.ChildNodes.Count; i++)
    {
      foreach (var nodeName in nodeNames)
      {
        if (!x[nodeName].InnerText.Equals(y[nodeName].InnerText))
          return false;
      }
    }

    // TODO some testing of attributes

    return true;
  }

  public int GetHashCode(XmlNode obj)
  {
    return 1;
  }
}

static void Main(string[] args)
{
  XmlDocument xdocA = new XmlDocument();
  xdocA.Load(pathA);
  XmlDocument xdocB = new XmlDocument();
  xdocB.Load(pathB);

  var nodesA = xdocA.SelectNodes("Root/value").Cast<XmlNode>();
  var nodesB = xdocB.SelectNodes("Root/value").Cast<XmlNode>();

  var comp = new NodeComparer();
  var errors = nodesA.Where(na => !nodesB.Contains(na, comp));

  if (errors.Count() > 0)
  {
    Console.WriteLine("ERRORS: ");
    foreach (var error in errors)
    {
      Console.WriteLine(string.Join(", ", error.Cast<XmlNode>().Select(xn => $"{xn.Name}: {xn.InnerText}")));
      Console.WriteLine();
    }
  }
  else
  {
    Console.WriteLine("No Errors");
  }

  Console.ReadLine();
}


}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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