比较xml文件

时间:2010-01-28 06:55:51

标签: c#

我有一个C#windows应用程序,我在尝试比较xml的内容。 基于xml文档的差异,我有进一步的处理。是否有一个内置的API来比较xml?

3 个答案:

答案 0 :(得分:1)

Microsoft XML Diff&修补程序工具具有以下API:http://msdn.microsoft.com/en-us/library/aa302294.aspx

答案 1 :(得分:0)

也许没有人再使用XML,但是我今晚需要创建一些代码来执行两个xml代码片段之间的比较,这些代码片段不关心元素顺序,除非元素被重复(包含列表)。对于包含列表,我确实要确保元素保持其原始顺序-确保未对其内容执行某种形式的意外排序。

public static class XmlCompare
{
    /// <summary>
    /// Compares xml docs without regard to element order, unless the elements are a nested list
    /// </summary>
    /// <param name="primary">Any valid xml</param>
    /// <param name="secondary">Any valid xml</param>
    public static void Compare(string primary, string secondary)
    {
        Compare(XElement.Parse(primary), XElement.Parse(secondary));
    }

    /// <summary>
    /// Compares xml docs without regard to element order, unless the elements are a nested list
    /// </summary>
    /// <param name="primary">Any valid xml</param>
    /// <param name="secondary">Any valid xml</param>
    public static void Compare(XElement primary, XElement secondary)
    {
        // iterate attributes found in primary; compare values
        foreach (XAttribute primaryAttribute in primary.Attributes())
        {
            var secondaryAttribute = secondary.Attribute(primaryAttribute.Name.LocalName);
            if (secondaryAttribute == null)
            {
                throw new Exception($"Element '{primary.Name.LocalName}' attribute '{primaryAttribute.Name.LocalName}' missing from secondary xml");
            }
            else
            {
                var primaryValue = primaryAttribute.Value;
                var secondaryValue = secondaryAttribute.Value;
                if (primaryValue != secondaryValue)
                    throw new Exception($"Element '{primary.Name.LocalName}' attribute '{primaryAttribute.Name.LocalName}' has an unequal value.  Expected '{primaryValue}', actual '{secondaryValue}'");
            }
        }

        // iterate attributes found in secondary; just ensure all attributes found in the secondary exist in the primary
        foreach (var secondaryAttribute in secondary.Attributes())
        {
            if (primary.Attribute(secondaryAttribute.Name.LocalName) == null)
                throw new Exception($"Element '{secondary.Name.LocalName}' attribute '{secondaryAttribute.Name.LocalName}' missing from primary xml");
        }

        // iterate elements of primary; compare values
        for (var i = 0; i < primary.Elements().Count(); i++)
        {
            var primaryElement = primary.Elements().Skip(i).Take(1).Single();
            var elementOccursMultipleTimes = primary.Elements(primaryElement.Name.LocalName).Count() > 1;
            if (elementOccursMultipleTimes)
            {
                // this comparison fails if the sequence of element entries has been altered between the primary
                // and secondary document, such as sorting a list by name in one document, but sorting by date
                // in the other.
                var secondaryElement = secondary.Elements().Skip(i).Take(1).SingleOrDefault();
                if (secondaryElement == null)
                {
                    throw new Exception($"Element '{primaryElement.Name.LocalName}' missing from secondary xml");
                }

                Compare(primaryElement, secondaryElement);
            }
            else
            {
                var secondaryElement = secondary.Element(primaryElement.Name.LocalName);
                if (secondaryElement == null)
                    throw new Exception($"Element '{primaryElement.Name.LocalName}' missing from secondary xml");
                // to understand recursion, we must first understand recursion
                Compare(primaryElement, secondaryElement);
            }
        }

        // iterate elements of secondary; just ensure all the elements found in the secondary exist in the primary
        foreach (var secondaryElement in secondary.Elements())
        {
            if (primary.Element(secondaryElement.Name.LocalName) == null)
                throw new Exception($"Element '{secondaryElement.Name.LocalName}' missing from primary xml");
        }
    }

希望这可以帮助某个人。

答案 2 :(得分:-1)

不确定,但您可以对2 xml片段进行反序列化,并对它们执行一个对象。