如何在使用XmlDiff比较2个Xml文件时丢失子节点? [英] How to get the child nodes missing on comparing 2 Xml files using XmlDiff?
问题描述
如何在使用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 whatstandard 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 ofBook
s 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屋!