只有当我的所有字段在XML中都有相同的数据时,我才需要删除重复项。但这里的问题是它不是List,而且我的字段名称也不同。 例如:
Scenario:1
<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test2</Name2A>
<Book2A>booktest2</Book2A>
<Page2A>pagetest2</Page2A>
</Items>
在这种情况下,我必须填充以上所有字段
Scenario 2:
<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test1</Name2A>
<Book2A>booktest1</Book2A>
<Page2A>pagetest1</Page2A>
</Items>
在这种情况下,我只需要填充<Name1A>,<Book1A>,<Page1A>
,因为在下一组字段中我的数据是相同的。
Scenario 3:
<Items>-->Not a List just an generic object Type T
<Name1A>test1</Name1A>
<Book1A>booktest1</Book1A>
<Page1A>pagetest1<Page2A>
<Name2A>test2</Name2A>
<Book2A>booktest1</Book2A>
<Page2A>pagetest1</Page2A>
</Items>
在这种情况下,我也希望填充所有字段,因为<Name2A>
数据不同。
答案 0 :(得分:0)
您需要一个班级来代表您的项目:
class Item {
public Item(String name, String book, String page) {
Name = name;
Book = book;
Page = page;
}
public String Name { get; }
public String Book { get; }
public String Page { get; }
}
你的XML非常奇怪,你需要编写一个小的解析器。可以使用迭代器块将输入序列(XElement
)转换为另一个序列(Item
):
IEnumerable<Item> ParseXml(XElement root) {
var elements = root.Elements().ToList();
if (elements.Count%3 != 0)
throw new ArgumentException("Number of XML child elements is not divisible by 3.");
for (var i = 0; i < elements.Count/3; i += 1) {
var nameElement = elements[3*i];
ThrowIfUnexpectedElement(nameElement, "Name", i + 1);
var bookElement = elements[3*i + 1];
ThrowIfUnexpectedElement(bookElement, "Book", i + 1);
var pageElement = elements[3*i + 2];
ThrowIfUnexpectedElement(pageElement, "Page", i + 1);
yield return new Item(
(String) nameElement,
(String) bookElement,
(String) pageElement
);
}
}
void ThrowIfUnexpectedElement(XElement element, String prefix, Int32 index) {
var expectedName = $"{prefix}{index}A";
if (element.Name.LocalName != expectedName)
throw new ArgumentException($"Unexpected XML element '{element.Name.LocalName}'. Expected '{expectedName}'.");
}
现在你可以解析XML了:
var items = ParseXml(xDocument.Root);
要删除重复项,您可以将Distinct()
与IEqualityComparer<Item>
结合使用:
class ItemEqualityComparer : IEqualityComparer<Item> {
public Boolean Equals(Item item1, Item item2) {
return item1.Name == item2.Name
&& item1.Book == item2.Book
&& item1.Page == item2.Page;
}
public Int32 GetHashCode(Item item) {
unchecked {
const Int32 Multiplier = -1521134295;
var hash = -175858345;
hash = hash*Multiplier + item.Name.GetHashCode();
hash = hash*Multiplier + item.Book.GetHashCode();
hash = hash*Multiplier + item.Page.GetHashCode();
return hash;
}
}
}
您可以使用以下代码获取不同的项目:
var distinctItems = items.Distinct(new ItemEqualityComparer());