Written by:
Microsoft
Microsoft
LINQ TO XML
Mar 05, 2009
Login to Rate
:( Error
0
0
Summary
Describes hows how to use LINQ to filter, group, sort, transform, and project an RSS feed.
You can parse XML data in Silverlight by using either Language-Integrated Query
(LINQ) to XML or the XmlReader class.
One common XML scenario is parsing and transforming RSS
feeds and displaying the content on a site. Because RSS is an XML format, LINQ to XML can be used to easily query and transform the
RSS feed.
RSS feeds typically contain news content, but they can contain anything that can be organized into discrete items.
In its simplest form, an RSS feed consists of a channel, which has a title, link, and description.
An RSS feed can also contain one or more item elements, each of which has a title, link, description,
and possibly other elements.
This QuickStart shows how to parse
an RSS feed of programming books. Specifically, this QuickStart shows how to
load the RSS feed, filter items by specified element, group items, sort items,
transform the shape of the XML tree, and control the projection type.
This QuickStart contains the following sections:
For a complete description of LINQ to XML, see Processing XML Data with LINQ to XML in Silverlight in the Silverlight documentation on MSDN.
Loading an RSS File
In Silverlight, you can load XML files in the following ways:
The following example shows how to load and display the RSS file from the application's XAP package.
C#
XElement rss = XElement.Load("rss.xml");
OutputTextBoxLoadRss.Text = rss.ToString();
Visual Basic
Dim rss As XElement = XElement.Load("rss.xml")
OutputTextBoxLoadRss.Text = rss.ToString()
The following shows the content of the RSS file.
<rss version="2.0">
<channel>
<title>Programming Books</title>
<link>http://www.books.microsoft.com</link>
<description>Download programming books</description>
<pubDate>Thu, 27 Apr 2008 13:40:10 +0000</pubDate>
<language>en</language>
<item>
<title> C# programming for beginners </title>
<link>http://www.books.microsoft.com/beginners-cs/</link>
<pubDate>Thu, 17 Apr 2008 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is C# for beginners. </description>
</item>
<item>
<title> VB programming for beginners </title>
<link>http://www.books.microsoft.com/beginners-vb/</link>
<pubDate>Thu, 15 Apr 2006 13:40:10 +0000</pubDate>
<category>Visual Basic</category>
<description> This is VB for beginners. </description>
</item>
<item>
<title> C# in Depth </title>
<link>http://www.books.microsoft.com/advanced-cs/</link>
<pubDate>Thu, 13 Dec 2007 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is advanced C# programming book. </description>
</item>
<item>
<title> VB in Depth </title>
<link>http://www.books.microsoft.com/advanced-vb/</link>
<pubDate>Thu, 17 Oct 2008 13:40:10 +0000</pubDate>
<category>Visual Basic</category>
<description> This is advanced VB programming book. </description>
</item>
</channel>
</rss>
Filtering an RSS XML Tree by Specific Elements
Often you want to work with a subset of XML data instead of the whole XML tree. In LINQ to XML,
you can combine querying with functional construction to generate a new XML document that has a
different shape from the original document. You can filter an XML document by specific elements to extract the data of interest.
The following example creates a query that finds item elements that have category child elements with a value of "C Sharp".
The query returns an IEnumerable of XElement. The result of the query is passed as a second parameter to the constructor of the XElement. Finally, the code outputs the content of the newly created XElement object to the page.
C#
XElement filterCategory =
new XElement("FilteringByCategory",
from category in rss.Element("channel").Elements("item")
where (string)category.Element("category") == "C Sharp"
select new XElement("item",
category.Elements()
)
);
OutputTextBoxFilter.Text = filterCategory.ToString();
Visual Basic
Dim filterCategory = <FilteringByCategory>
<%= From category In rss.<channel>.<item> _
Where category.<category>.Value.Contains("C Sharp") _
Select _
<item>
<%= category.Elements %>
</item> _
%></FilteringByCategory>
OutputTextBoxFilter.Text = filterCategory.ToString()
The following shows the query output of filtering by the "C Sharp" category.
<FilteringByCategory>
<item>
<title> C# programming for beginners </title>
<link>http://www.books.microsoft.com/beginners-cs/</link>
<pubDate>Thu, 17 Apr 2008 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is C# for beginners. </description>
</item>
<item>
<title> C# in Depth </title>
<link>http://www.books.microsoft.com/advanced-cs/</link>
<pubDate>Thu, 13 Dec 2007 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is advanced C# programming book. </description>
</item>
</FilteringByCategory>
Grouping an RSS XML Tree by Category
In many reports, you need to organize data into groups to make it easier to read and to analyze.
The following example shows how to group data, and then generate XML based on the grouping.
The example creates a query that groups item elements by category. The query returns an IEnumerable of XElement.
The result of the query is passed as a second parameter to the constructor of the XElement. Finally, the code outputs the content of the newly created XElement object to the page.
C#
XElement groupCategory =
new XElement("GroupingByCategory",
from item in rss.Element("channel").Elements("item")
group item by (string)item.Element("category") into groupedData
select new XElement("group",
new XAttribute("Name", groupedData.Key),
from g in groupedData
select new XElement("item",
g.Elements())
)
);
OutputTextBoxGroup.Text = groupCategory.ToString();
Visual Basic
Dim groupCategory = <GroupingByCategory>
<%= From item In rss.<channel>.<item> _
Group By item = item.<category>.Value _
Into groupedData = Group _
Select _
<group Name=<%= item %>>
<%= From g In groupedData _
Select _
<item>
<%= g.Elements %>
</item> %>
</group> %>
</GroupingByCategory>
OutputTextBoxGroup.Text = groupCategory.ToString()
The following shows the query output of grouping by category.
<GroupingByCategory>
<group Name="C Sharp">
<item>
<title> C# programming for beginners </title>
<link>http://www.books.microsoft.com/beginners-cs/</link>
<pubDate>Thu, 17 Apr 2008 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is C# for beginners. </description>
</item>
<item>
<title> C# in Depth </title>
<link>http://www.books.microsoft.com/advanced-cs/</link>
<pubDate>Thu, 13 Dec 2007 13:40:10 +0000</pubDate>
<category>C Sharp</category>
<description> This is advanced C# programming book. </description>
</item>
</group>
<group Name="Visual Basic">
<item>
<title> VB programming for beginners </title>
<link>http://www.books.microsoft.com/beginners-vb/</link>
<pubDate>Thu, 15 Apr 2006 13:40:10 +0000</pubDate>
<category>Visual Basic</category>
<description> This is VB for beginners. </description>
</item>
<item>
<title> VB in Depth </title>
<link>http://www.books.microsoft.com/advanced-vb/</link>
<pubDate>Thu, 17 Oct 2008 13:40:10 +0000</pubDate>
<category>Visual Basic</category>
<description> This is advanced VB programming book. </description>
</item>
</group>
</GroupingByCategory>
Sorting an RSS XML Tree by Title
Sometimes you need to extract certain elements from an XML tree and display them in sorted order.
The following example shows how to write a query that sorts its results.
The example creates a query that sorts item elements by title. The query returns an IEnumerable of String.
C#
IEnumerable<String> sortedTitles =
from item in rss.Elements("channel").Elements("item")
let title = (String)item.Element("title")
orderby title
select title;
StringBuilder sb = new StringBuilder();
sb.AppendLine("Sorting by Title:");
foreach (String bookTitle in sortedTitles)
sb.AppendLine(bookTitle.ToString());
OutputTextBoxSort.Text = sb.ToString();
Visual Basic
Dim sortedTitles As IEnumerable(Of String) = _
From item In rss.<channel>.<item> _
Let title = Convert.ToString(item.<title>.Value) _
Order By (title) _
Select title
Dim sb As New StringBuilder
sb.AppendLine("Sorting by Title:")
Dim bookTitle As String
For Each bookTitle In sortedTitles
sb.AppendLine(bookTitle.ToString())
Next bookTitle
OutputTextBoxSort.Text = sb.ToString()
The following shows the query output of sorting by title.
Sorting by Title:
C# in Depth
C# programming for beginners
VB in Depth
VB programming for beginners
Transforming the Shape of an RSS XML Tree
The shape of an XML document refers to its element names, attribute names, and the characteristics of its hierarchy.
Sometimes you have to change the shape of an XML document. For example, you might have to send an existing XML document to
another system that requires different element and attribute names.
The following example changes the shape of an XML file by using embedded query expressions.
The source XML document contains a channel element under the rss root element. The channel element has a title, link, description, and
item elements, each of which has a title, link, description, and other elements.
The transformed XML tree contains book elements under the TransformingShape element that contains category,
title, and pubDate child elements.
C#
XElement transformShape =
new XElement("TransformingShape",
from item in rss.Elements("channel").Elements("item")
select new XElement("book",
item.Elements("category"),
item.Elements("title"),
item.Elements("pubDate"))
);
OutputTextBoxTransform.Text = transformShape.ToString();
Visual Basic
Dim transformShape = <TransformingShape>
<%= From item In rss.<channel>.<item> _
Select <book>
<%= item.<category> %>
<%= item.<title> %>
<%= item.<pubDate> %>
</book> %>
</TransformingShape>
OutputTextBoxTransform.Text = transformShape.ToString()
The following shows the query output of transforming the shape.
<TransformingShape>
<book>
<category>C Sharp</category>
<title> C# programming for beginners </title>
<pubDate>Thu, 17 Apr 2008 13:40:10 +0000</pubDate>
</book>
<book>
<category>Visual Basic</category>
<title> VB programming for beginners </title>
<pubDate>Thu, 15 Apr 2006 13:40:10 +0000</pubDate>
</book>
<book>
<category>C Sharp</category>
<title> C# in Depth </title>
<pubDate>Thu, 13 Dec 2007 13:40:10 +0000</pubDate>
</book>
<book>
<category>Visual Basic</category>
<title> VB in Depth </title>
<pubDate>Thu, 17 Oct 2008 13:40:10 +0000</pubDate>
</book>
</TransformingShape>
Controlling the Type of a Projection
Projection is the process of taking one set of data, filtering it, changing its shape, and even changing its type.
Most query expressions perform projections. Most of the query expressions shown in this topic evaluate to IEnumerable of XElement.
However, you can control the type of the projection to create collections of other types.
The following example defines a new type, Book. The query expression then instantiates new Book objects in the Select clause.
This causes the type of the query expression to be IEnumerable of Book.
C#
public partial class Page : UserControl
{
public class Book
{
private string category;
private string title;
public Book(string category, string title)
{
this.category = category;
this.title = title;
}
public override string ToString()
{
return String.Format("Category: {0} " +
"Title:{1}", this.category, this.title);
}
}
void ControllingProjectionType(XElement rss)
{
IEnumerable<Book> bookList =
from item in rss.Elements("channel").Elements("item")
select new Book(
(string)item.Element("category"),
(string)item.Element("title")
);
StringBuilder sb = new StringBuilder();
sb.AppendLine("Controlling Projection Type:");
foreach (Book book in bookList)
sb.AppendLine(book.ToString());
OutputTextBoxControlType.Text = sb.ToString();
}
public Page()
{
InitializeComponent();
// Load the rss file.
XElement rss = XElement.Load("rss.xml");
ControllingProjectionType(rss);
}
}
Visual Basic
Partial Public Class Page
Inherits UserControl
Public Class Book
Private category As String
Private title As String
Public Sub New(ByVal category As String, _
ByVal title As String)
Me.category = category
Me.title = title
End Sub
Public Overrides Function ToString() As String
Return String.Format("Category: {0} " & _
"Title:{1}", Me.category, Me.title)
End Function
End Class
Sub ControllingProjectionType(ByVal rss As XElement)
Dim bookList As IEnumerable(Of Book) = _
From item In rss.<channel>.<item> _
Select New Book( _
item.<category>.Value, _
item.<title>.Value)
Dim sb As New StringBuilder()
sb.AppendLine("ControllingType:")
Dim book As Book
For Each book In bookList
sb.AppendLine(book.ToString())
Next book
OutputTextBoxControlType.Text = sb.ToString()
End Sub 'ControlProjectionType
Public Sub New()
InitializeComponent()
Dim rss As XElement = XElement.Load("rss.xml")
ControllingProjectionType(rss)
End Sub
End Class
The following shows the output of the projection to a Book type.
Controlling Projection Type:
Category: C Sharp Title: C# programming for beginners
Category: Visual Basic Title: VB programming for beginners
Category: C Sharp Title: C# in Depth
Category: Visual Basic Title: VB in Depth
See Also
Send Feedback