Introduction
This article explains how to use Linq with XML using the XSD file.
The aim of using Linq to XSD is to enhance Linq to XML by having more features, strong typed fields,...
This article provides a way to use an XML database through the new Linq To XSD technology.
It does not enumerate all possibilities, all error cases..., but just gives the reader what is needed to start working.
Background
Before reading this article, you must have some LINQ, XML and XSD bases. Please refer to following links if you're not familiar with those technologies:
Another LINQ to Something
This technology may be used to manage with XML database.
I've started searching information LINQ To XML to process queries other than my XML database. But I did not like the syntax for queries, because it is very blur and not strong typed. Finally code is not readable and may be hard to understand for beginners. I was searching for something very simple and easy to use.
In fact, I would like to write the simplest code (What else?) and manage my data without any effort! LINQ to XSD makes it for us! So you just need money, girls and whisky ;-)
Prerequisites and Warnings
Before creating a new project, you need to install the LINQ To XSD alpha 2 Refresh on your computer. It is an alpha software, so install it carefully.
The Database
To use Linq To XSD, you must have an XSD file which describes and validates your XML database schema.
In the sample zipped file, you will find a Database directory which includes an XML database with its associated XSD schema file.
XSD File
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="urn:books"
xmlns:bks="urn:books">
<xsd:element name="books" type="bks:BooksForm"/>
<xsd:complexType name="BooksForm">
<xsd:sequence>
<xsd:element name="book"
type="bks:BookForm"
minOccurs="0"
maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="BookForm">
<xsd:sequence>
<xsd:element name="author" type="xsd:string"/>
<xsd:element name="title" type="xsd:string"/>
<xsd:element name="genre" type="xsd:string"/>
<xsd:element name="price" type="xsd:float" />
<xsd:element name="pub_date" type="xsd:date" />
<xsd:element name="review" type="xsd:string"/>
</xsd:sequence>
<xsd:attribute name="id" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
XML Database File
="1.0"
<x:books xmlns:x="urn:books">
<book id="bk001">
<author>Robert E. Howard</author>
<title>The Coming of Conan the Cimmerian</title>
<genre>Science Fiction & Fantasy</genre>
<price>44.95</price>
<pub_date>2003-12-02</pub_date>
<review>Conan let go, spat blood from his mouth..</review>
</book>
<book id="bk002">
<author>Terry Goodkind</author>
<title>Wizard's First Rule</title>
<genre>Fantasy</genre>
<price>24.95</price>
<pub_date>2001-06-23</pub_date>
<review>My world contest best book</review>
</book>
<book id="bk003">
<author>HP Lovecraft</author>
<title>Call of Cthulhu</title>
<genre>Science Fiction & Fantasy</genre>
<price>42</price>
<review>I am writing this under an appreciable mental strain,
since by tonight I shall be no more...</review>
</book>
</x:books>
Creating a New Project
After having installed Linq To XSD, just open Visual Studio 2008 and create a new Linq to XSD project.
Then add an XSD file to the project (either create a new one, or import an existing one).
Finally, just change the build options for the XSD file. Open XSD file properties from the Solution Explorer, and change the Build action to LinqToXSDSchema
.
Just build your project, and then you are now ready to use Linq with another XML file!! Amazing!!
Opening an XML Database
Note: If you have specified a namespace in XSD file, then the same namespace is available from C#, with all classes included!
In sample XSD/XML files, I used the namespace urn::books::
.
urn.books.books m_books_database = urn.books.books.Load("books.xml");
Queries
Then, you may directly use the m_books_database
object inside LINQ queries:
var list_books = from c in m_books_database.book
select c;
Now, the list_books
contains the full list of books from your XML file. So you can manage data by using a foreach
or sending it to a databindable control for example.
Another query with a specific output value (Title (Author) : Price
):
var list_books_title = from c in m_books_database.book
select c.title + " (" + c.author + ") Price:" +
c.price.ToString() + "$";
listBox1.DataSource = list_books_title.ToList();
Modify XML Data
To modify an XML attribute with Linq, you just need to query any object, modify its properties and finally save
the database.
var book001 = from c in m_books_database.book
where c.id.CompareTo("bk001")==0
select c;
book001.First().price = 1234;
m_books_database.Save("books2.xml");
Removing and Creating Elements
Remove a Book
To delete an XML element, just query the object and call the Remove
method of the database instance.
var book001 = from c in m_books_database.book
where c.id.CompareTo("bk001")==0
select c;
foreach (var b in book001)
m_books_database.book.Remove(b);
Create a New Book
To create a new XML element, just create a local object and add this item to the database instance.
urn.books.BookForm itemToAdd = new urn.books.BookForm();
itemToAdd.author = "Andrew Troelsen";
itemToAdd.genre="Programming";
itemToAdd.id="bk004";
itemToAdd.price=37.79f;
itemToAdd.pub_date=Convert.ToDateTime("2007-12-07");
itemToAdd.title = "Pro C# 2008 and the .NET 3.5 Platform";
m_books_database.book.Add(itemToAdd);
Strong Typed and Intellisense
One of the main interests of Linq To XSD (compared to Linq To XML) is that objects are strongly typed and can then directly be used by intellisense.
So it provides a very good way to gain productivity and avoid runtime errors. (The build detects errors because objects are really typed).
Points of Interest
- Easy to use
- Lesser code needed, so fewer bugs...
- Fast implementation
- Better than Linq To XML
- Fully integrated by intellisense
- Code is readable
Remaining Points
- Linq to XSD is "Preview alpha"
- Are the queries fast enough on large XML files?
References
History
- 4th November, 2008: Initial version