#xml #linq
#xml #linq
Вопрос:
Я создаю RSS-ридер, в котором будут загружаться только самые последние сообщения от разных авторов, что означает, что в каждом исходном блоге есть только одно сообщение. Следующий фрагмент кода создает ряд кнопок в окне списка, каждая из которых содержит название блога и дату публикации публикации в виде текста, а также ссылку на блог при нажатии. Слишком много кнопок, потому что для каждой публикации требуется по одной.
Я хотел бы знать, как создать IEnumerable blogPosts только с объектными блогами, где Blog Name отличается. Я не знаю, должен ли это быть более усовершенствованный запрос Linq (я пробовал это во многих вариантах, но безрезультатно) или цикл по постам в блогах, чтобы каким-то образом аннулировать все эти блоги с дублирующими именами в качестве названий.
private void client_DownloadStringCompleted(object sender,
DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
//declare the document xml to parse
XDocument LABlogs = XDocument.Parse(e.Result);
//declare the namespace of the xml to parse
XNamespace xmlns = "http://www.w3.org/2005/Atom";
//set the variable to collect the content for the buttons in the blogList ListBox
//I'm parsing two nodes on the same level, then thier descendants both element and attribute
var blogPosts = from source in LABlogs.Descendants(xmlns "source")
from entry in LABlogs.Descendants(xmlns "entry")
//someplace here I want to filter to where the source is distinct
select new Blog
{
//parsing the feed to get the button properties
BlogName =(string)source.Element(xmlns "title").Value,
BlogUrl = (string)source.Element(xmlns "link").Attribute("href").Value,
BlogPub = (string)entry.Element(xmlns "published").Value
};
//add the var containing the button properties to the ListBox
this.blogListBox.ItemsSource = blogPosts;
}
}
}
public class Blog
{
public string BlogName { get; set; }
public string BlogUrl { get; set; }
public string BlogPub { get; set; }
}
Комментарии:
1. Что вы получаете сейчас? Никто не собирается тратить время на отладку вашей программы за вас. Вы должны задать конкретный вопрос.
2. Это позволяет загрузить ряд кнопок в listbox с именем блога и BlogPub (дата публикации) в виде текста на кнопке, а ссылки на BlogUrl выводятся. В настоящее время он загружает одну кнопку для каждого опубликованного сообщения, но мне нужна одна кнопка для каждого блога. Я не знаю, как реализовать Distinct для BlogName (или где это реализовать), чтобы повлиять на весь пост в блоге.
Ответ №1:
Вы можете использовать отличный метод Linq, передавая IEqualityComparer:
private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error == null)
{
//declare the document xml to parse
XDocument LABlogs = XDocument.Parse(e.Result);
//declare the namespace of the xml to parse
XNamespace xmlns = "http://www.w3.org/2005/Atom";
//set the variable to collect the content for the buttons in the blogList ListBox
//I'm parsing two nodes on the same level, then thier descendants both element and attribute
var blogPosts = from source in LABlogs.Descendants(xmlns "source")
from entry in LABlogs.Descendants(xmlns "entry")
//someplace here I want to filter to where the source is distinct
select new Blog
{
//parsing the feed to get the button properties
BlogName = (string)source.Element(xmlns "title").Value,
BlogUrl = (string)source.Element(xmlns "link").Attribute("href").Value,
BlogPub = (string)entry.Element(xmlns "published").Value
};
// ******************************** //
// >>>> here is the Distinct code <<<<
// ******************************** //
blogPosts.Distinct(new BlogNameComparer());
//add the var containing the button properties to the ListBox
this.blogListBox.ItemsSource = blogPosts;
}
}
Код средства сравнения равенства:
public class BlogNameComparer : IEqualityComparer<Blog>
{
bool IEqualityComparer<Blog>.Equals(Blog x, Blog y)
{
if (x == null) return y == null;
if (y == null) return false;
return string.Equals(x.BlogName, y.BlogName);
}
int IEqualityComparer<Blog>.GetHashCode(Blog obj)
{
if (obj == null) return 0;
return obj.BlogName.GetHashCode();
}
}
Комментарии:
1. xxxooo! Это работает как шарм. Единственное, что мне нужно было добавить в список разные записи в блогах, вот так
this.blogListBox.ItemsSource = blogPosts.Distinct(new BlogNameComparer());
Для меня это очень полезная информация; еще раз спасибо.