C#中的Xpath:从xml“list”中获取元素(兄弟姐妹)

时间:2015-02-05 18:00:44

标签: c# xml select xpath

我的问题很简单。我正在使用XPath从xml文件中检索信息。我的目标是比较2个XML文件,它们应该是相同的。我对“单个”节点没有任何问题。当有兄弟姐妹时,我的问题出现了。

看起来像是:

XPathDocument expectedDocument = new XPathDocument("C:\\expected.xml");
XPathDocument testedDocument = new XPathDocument("C:\\tested.xml");
XPathNavigator expectedNav = expectedDocument.CreateNavigator();
XPathNavigator testedNav = testedDocument.CreateNavigator();
XPathNodeIterator expectedIterator;
XPathNodeIterator testedIterator;
string expectedStr;
string testedStr;
string parameter;
parameter = "/DonneesDepot/Identification/@CoclicoFacturation";
expectedStr = expectedNav.SelectSingleNode(parameter).Value;
testedStr = testedNav.SelectSingleNode(parameter).Value;
CompareValues(expectedStr, testedStr, parameter);

完美无缺。现在它变得复杂的是这种XML:

  <Surtaxe>
        <Zone CodeZoneSurtaxe="1" NbPlisZone="0" PoidsZone="0" />
        <Zone CodeZoneSurtaxe="2" NbPlisZone="2" PoidsZone="2" />
  </Surtaxe>

我希望能够确保两个文件中“Surtaxe”的内容相同(请记住顺序并不重要),所以我尝试了这个:

parameter = "/DonneesDepot/Facturation/Surtaxe/Zone/@PoidsZone";
expectedIterator = expectedNav.Select(parameter);
testedIterator = testedNav.Select(parameter);
while (expectedIterator.MoveNext() && testedIterator.MoveNext())
{
    CompareValues(expectedIterator.Current.Value, testedIterator.Current.Value, parameter);
}

但即使XML都包含两行,它们有时也不是同一个顺序,所以我的while循环不起作用。

最容易比较两个以下的内容(此比较的预期结果将是“平等”)

<Surtaxe>
    <Zone CodeZoneSurtaxe="1" NbPlisZone="1" PoidsZone="1" />
    <Zone CodeZoneSurtaxe="2" NbPlisZone="0" PoidsZone="0" />
</Surtaxe>

<Surtaxe>
    <Zone CodeZoneSurtaxe="2" NbPlisZone="0" PoidsZone="0" />
    <Zone CodeZoneSurtaxe="1" NbPlisZone="1" PoidsZone="1" />
</Surtaxe>

谢谢

1 个答案:

答案 0 :(得分:1)

这将做你想要的,你可能需要为你的真实对象更改它,但这应该让你开始。我证明了2个解决方案。一个天真的n ^ 2解决方案和一个应该更快的排序方法。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace XmlCompare
{
    using System.IO;
    using System.Xml.Linq;
    using System.Xml.XPath;

    class Program
    {

        private static string xml1 = "<Surtaxe>" + "<Zone CodeZoneSurtaxe=\"2\" NbPlisZone=\"0\" PoidsZone=\"0\" />"
                                     + "<Zone CodeZoneSurtaxe=\"1\" NbPlisZone=\"1\" PoidsZone=\"1\" />" + "</Surtaxe>";

        private static string xml2 = "<Surtaxe>" + "<Zone CodeZoneSurtaxe=\"1\" NbPlisZone=\"1\" PoidsZone=\"1\" />"
                                     + "<Zone CodeZoneSurtaxe=\"2\" NbPlisZone=\"0\" PoidsZone=\"0\" />" + "</Surtaxe>";

        private static void Main(string[] args)
        {

            var expectedDoc = XDocument.Load(new StringReader(xml1));
            var testedDoc = XDocument.Load(new StringReader(xml2));
            var success = true;

            //naive
            foreach (var node in expectedDoc.Descendants("Surtaxe").First().Descendants())
            {
                if (testedDoc.Descendants(node.Name).FirstOrDefault(x => x.ToString()== node.ToString()) == null)
                {
                    success = false;
                    break;
                }
            }

            //sort
            var sortedExpected = xml1.ToList();
            sortedExpected.Sort();

            var testSorted = xml2.ToList();
            testSorted.Sort();

            success = new string(sortedExpected.ToArray()).Equals(new string(testSorted.ToArray()));

            Console.WriteLine("Match? " + success);
            Console.ReadKey();

        }
    }
}