My first blog entry: Jumping into the LINQ to XML swimming pool!

 

This is a day of firsts.

Not only my first technical blog entry, but also my first .NET 3.5 program, and the first time I use LINQ

I installed Visual Studio 2008 immediately after the Heroes Happen {Here} event in Sydney, but have mostly used it to edit and add to existing .NET 2.0 applications.

LINQ has intrigued me for a while, specially LINQ to XML, but all the demos I have seen so far have been relevant to LINQ to SQL and LINQ to Objects.

Then yesterday, I received an email from Experts Exchange asking me to help out with a question on XML.

I have been a member of Experts Exchange since 2003, when I was struggling with the steep learning curve from VB6 to .NET.

And this learning curve was a hard one to master: Today you just Google a few keywords and you probably will find at least two good examples that will answer any question you have. Not so in those days. The books on .NET were just thick hard copies of the help system, with hardly any good examples to choose from.

My first experts exchange question simply stated: How do I read data from a particular source, then update the same source, or another one? Today this would have been considered a naive question, but in those days, moving from an ADO frame of mind to the disconnected DataSet concept was not easy.

Getting back to the point:

In this particular question, the asker is in a similar situation: He is trying to use LINQ to do the simple task of adding an XmlNode to an existing document. He knows a little LINQ using VB.NET, but is stuck and does not understand the exception his code is causing.

Sounds so simple an easy!

But after two days, and two calls for help from more experienced experts who received an email similar to the one I got, the question still was unanswered.

"Well", I thought to myself, "it is time to get myself acquainted with the new technology". Best way to learn to swim is to jump into the pool.

First Step: Google for "LINQ to XML"

2 minutes later I link to "LINQ to XML – 5 Minute Overview". Sounds quite promising! OK, so now we have XElements and XAttributes instead of XmlElements and XmlAttributes. Must be easy then to just solve the problem with the ‘ol XmlDocument type of objects, but using instances of these classes instead.

First try:

Use part of the asker’s code:

Dim xmlTrack as XElement=
                      <track id="45"> <trackId>45</trackId> </track>

Dim doc as XmlDocument = new XmlDocument() ‘Now lets see how I add an XElement to it.

Intellisense, help me out!!!  No luck…. I am still using the older classes!

Ahh… It is XDocument I have to use… makes sense!

Second try

Dim doc as XDocument = new XDocument()

doc.Load(sPath) ‘sPath points to the document which starts with <tracks><track>….

doc.Add(track) ‘Geee.. This is sooo easy!!! Lets test it and claim victory

Oh Nooo!!!… InvalidOperationException was unhandled. This operation would create an incorrectly structured document. 😦

Ok.. that makes sense. The DocumentElement is <tracks>…</tracks>, and I am adding <track> to the end of the document, hence the document will not have one root element, and hence it is not structured properly.
What I need to do is to add a child to <tracks>… should be easy…. but… There is no .AddChild, or .Children in intellisense!!! mmmm….

Intellisense aided attempts:

doc.AddAfterSelf(track)
doc.AddFirst(track)
doc.FirstNode.AddAfterSelf(track)
doc.LastNode.AddBeforeSelf(track)

All fail. In short, they all try to do the same thing as before as the Documents first (and last) node is still <tracks>. GRRRR. How do I get to the inner <track> node and then use AddAfterSelf or AddLast?

Time to Google for an answer: "XElement first child Dim" (Adding Dim guarantees VB.NET examples, use C# in the search otherwise)

LINQ To XML Samples – DML give me the clue I need and the final code looks like this:

Dim sPath = "tracks.xml"
Dim doc As XDocument

If File.Exists(sPath) Then
    doc = XDocument.Load(sPath)
    Dim track As XElement =
                            <track id="45">
                                <trackId>45</trackId>
                            </track>

    ‘Dim Tracks = doc.<tracks> ***** First attempt. Still does not work. Still same problem as above ******
    Dim Tracks = doc.<tracks>.<track> ‘It is so easy once you get the hang of it! It still is confusing though, but you should compare this with an XPath //tracks/track statement, which will return all <track> nodes
    Tracks.Last().AddAfterSelf(track)
    doc.Save(sPath)
End If

The complete question and solution at Experts Exchange can be seen here

This entry was posted in .NET programming. Bookmark the permalink.

3 Responses to My first blog entry: Jumping into the LINQ to XML swimming pool!

  1. Antonio says:

    Hi Daniel!I liked your post because it exemplifies several things neatly at the same time: how to use the internet to get answers, a brief tutorial on LINQ to XML, the train of thought of a developer and even some history of battles of old! I think its a funny coincidence that exactly yesterday I started to flirt with LINQ to XML, going to the same places you did. I already have done some stuff with LINQ to SQL but that hasn\’t really provided me with experience in dealing with XML besides the LINQ query syntax. Unfortunately for my project I found simple XML serialization is better but I hope to get back to LINQX later.Good luck with your tech posts! May they be as useful and enjoyable as this one.

  2. Casey says:

    Thanks this helped. I was getting the InvalidOperationException b/c I was missing a root node.

  3. Louis says:

    Nice work. Much better documented than anything Microsoft puts out there.

Leave a comment