如何在使用XmlDiff比较2个Xml文件时丢失子节点? [英] How to get the child nodes missing on comparing 2 Xml files using XmlDiff?

查看:68
本文介绍了如何在使用XmlDiff比较2个Xml文件时丢失子节点?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在使用XmlDiff比较2个Xml文件时丢失子节点?



我想只显示输入Xml中缺少的元素节点与标准Xml。使用XmlDiff节点时,还会显示值更改。我只想要缺少节点元素而不是节点值不匹配。

How to get the child nodes missing on comparing 2 Xml files using XmlDiff?

I want to show only the missing element nodes in the input Xml comparing with the standard Xml. With XmlDiff node value changes also are shown. I just want the missing node elements and not the node value mismatch.

推荐答案

我不明白你的意思只显示缺少的元素节点输入Xml与标准Xml 相比,特别是标准xml 是......然而......



有 - 至少 - 两种解决方案:

1)使用模式进行XML验证(XSD文件)

如何:使用XSD验证(LINQ to XML) [ ^ ]

使用XmlSchemaSet进行XML模式(XSD)验证 [ ^ ]

XmlDocument.Validate方法(ValidationEventHandler) [ ^ ]



2)数据对比使用自定义类(和类集合)和 IEqualityComparer< T> [ ^ ]和 Enumerable.Except() [ ^ ]方法:

第二种方法有点难以解释,所以...最好的方法是展示一个例子(请阅读评论)。

想象一下,你有一个 Book 的列表,其中包含以下属性: Id Ti tle 作者。示例类可能如下所示:

I have no idea what you mean by "show only the missing element nodes in the input Xml comparing with the standard Xml", especially what standard xml is... Nevertheless...

There are - at least - two solutions:
1) XML validation using schema (XSD file)
How to: Validate Using XSD (LINQ to XML)[^]
XML Schema (XSD) Validation with XmlSchemaSet[^]
XmlDocument.Validate Method (ValidationEventHandler)[^]

2) Data comparison using custom class (and class collection) and IEqualityComparer<T>[^] and Enumerable.Except()[^] method:
Second method is bit harder to explain, so... the best method is to show an example (please read comments).
Imagine, you have a list of Books with the following properties: Id, Title, Author. Example class may look like:
public class Book
{
    private int id = 0;
    private string author = string.Empty;
    private string title = string.Empty;

    public Book(int _id, string _author, string _title)
    {
        id = _id;
        author = _author;
        title = _title;
    }

    public int Id
    {
        get { return id; }
        set { id = value; }
    }

    public string Author
    {
        get { return author; }
        set { author = value; }
    }

    public string Title
    {
        get { return title; }
        set { title = value; }
    }
}





IEqualityComparer类可能如下所示:



IEqualityComparer class may look like:

public class BookComparer : IEqualityComparer<Book>
{

    public bool Equals(Book a, Book b)
    {
        if (Object.ReferenceEquals(a, b)) return true;

        //Check whether the products' properties are equal.
        return a != null && b != null && a.Title.Equals(b.Title) && a.Author.Equals(b.Author);
    }

    public int GetHashCode(Book obj)
    {
        int hashBookTitle = obj.Title == null ? 0 : obj.Title.GetHashCode();
        int hashBookAuthor = obj.Author == null ? 0 : obj.Author.GetHashCode();

        //Calculate the hash code for the book
        return hashBookTitle ^ hashBookAuthor;
    }
}



如您所见, Id 属性被忽略。仅比较标题作者



现在,我们将在下一步中使用示例xml数据:


As you can see, Id property is ignored. Only Title and Author of book are compared.

Now, sample xml data, which we'll use in next step:

<books>
  <book id="1">
    <author>James Booldog</author>
    <title>The honor </title>
  </book>
  <book id="2">
    <author>Joanne Clipboard</author>
    <title>Paranoya</title>
  </book>
  <book id="3">
    <author>Jamie Douplo</author>
    <title>Lego star</title>
  </book>
</books>





用法:



Usage:

void Main()
{
    //define xml content
    //first xml
    string x1 = @"<?xml version='1.0' encoding='utf-8'?>
    <books>
        <book id='1'>
            <author>James Booldog</author>
            <title>The honor </title>
        </book>
        <book id='2'>
            <author>Joanne Clipboard</author>
            <title>Paranoya</title>
        </book>
        <book id='3'>
            <author>Jamie Douplo</author>
            <title>Lego star</title>
        </book>
    </books>";
    //second xml
    string x2 = @"<?xml version='1.0' encoding='utf-8'?>
    <books>
        <book id='1'>
            <author>James Booldog</author>
            <title>The honor </title>
        </book>
        <book id='2'>
            <author>Joanne Clipboard</author>
            <title>Paranoya</title>
        </book>
        <book id='3'>
        </book>
    </books>";
    //create xml documents
    XDocument doc1 = XDocument.Parse(x1);
    //doc1.Dump();
    XDocument doc2 = XDocument.Parse(x2);
    //returns List<Book>
    List<Book> bks1 = doc1.Descendants("book")
        .Select(x=>new Book
            (
                (int)x.Attribute("id"),
                (string)x.Element("author"),
                (string)x.Element("title")
            )).ToList<Book>();
    //returns IEnumerable<Book>
    var bks2 = doc2.Descendants("book")
        .Select(x=>new Book
            (
                (int)x.Attribute("id"),
                (string)x.Element("author"),
                (string)x.Element("title")
            ));

    //compare List(of Book) using BookComparer class, which inherits from IEqualityComparer
    var missingBooks1 = bks1.Except(bks2, new BookComparer());
}





如果你使用自定义集合类:



In case when you use custom collection class:

public class Books : CollectionBase
{

    public void Add(Book b)
    {
        //b.Id = List.Count;
        List.Add(b);
    }

    public void AddRange(List<Book> books)
    {
        foreach(Book b in books)
        {
            List.Add(b);
        }
    }

    public void AddRange(IEnumerable<Book> books)
    {
        foreach(var b in books)
        {
            List.Add((Book)b);
        }
    }

    public void Remove(int index)
    {
        if(index<0 || index>List.Count-1)
        {
            throw new IndexOutOfRangeException("Invalid index!");
        }
        else
        {
            List.Remove(index);
        }
    }

}





a比较可能是这样实现的:



a comparison might be achieved this way:

//using Books class which inherits from CollectionBase
Books books1 = new Books();
books1.AddRange(bks1);
Books books2 = new Books();
books2.AddRange(bks2);
//compare
var missingBooks2 = books1.Cast<Book>().Select(a=>a).Except(books2.Cast<Book>().Select(b=>b), new BookComparer());







最后说明:这是一个非常基本的例子。我希望你有个主意。

尝试实现自己的方法来比较xml数据!




Final note: This is very basic example. I hope you get an idea.
Try to implement your own method to compare xml data!


这篇关于如何在使用XmlDiff比较2个Xml文件时丢失子节点?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆