Tuesday, September 04, 2007 12:00 AM bart

Visual Basic 9.0 Feature Focus - XML Support

Welcome back to the Visual Basic 9.0 Feature Focus blog series. In this post, we'll cover a feature unique to Visual Basic: XML Support. In VB 9.0, XML has become a first class citizen of the language, meaning you can use XML literals to build XML fragments (sounds pretty logical isn't it?) together with a few operators that make working with XML really simple (and I mean really simple). Combine this with support for XSD schemas and you get a superb language feature. Let's take a closer look...

First of all, take a look at the Inline XML syntax:

Dim xml = <Books>
                      <Book Title="Introducing VB 9.0" Price="0.00">
                          <Author>Bart De Smet</Author>
                      </Book>
                      <Book Title="Introducing C# 3.0" Price="0.00">
                          <Author>Bart Simpson</Author>
                      </Book>
                  </Books>

Not very exciting is it? Just plain XML inside the program, combined with and Implicitly Type Local Variable. So, what's the type of the xml variable in the fragment above? Drumroll ... it's an XElement. No, not an XmlElement, but an XElement without the 'ml'. XElement is defined in a new .NET Framework 3.5 namespace, called System.Xml.Linq that's included by default in new VB 9.0 applications. So, why do we have a new XML API in .NET? The answer is simple: make things easier and composable. If there's one thing the System.Xml implementation - based on the DOM - lacks, it's composability. Imagine you have to construct the XML piece from the code above using the System.Xml API. You'd end up with spaghetti like this:

Dim doc As New XmlDocument()
Dim books As XmlElement = doc.CreateElement("Books")

Dim book1 As XmlElement = doc.CreateElement("Book")
Dim title1 As XmlAttribute = doc.CreateAttribute("Title")
title1.Value = "Introducing VB 9.0"
book1.Attributes.Append(title1)
Dim title2 As XmlAttribute = doc.CreateAttribute("Price")
title2.Value = "0.00"
book1.Attributes.Append(title2)
Dim author1 As XmlElement = doc.CreateElement("Author")
author1.InnerText = "Bart Simpson"
book1.AppendChild(author1)
books.AppendChild(book1)

The code fragment above just defines one single book by the way... I do have only one question for you: can you still smell the XML in the code above? Apart from the language integration in VB 9.0, the new System.Xml.Linq API is much more composable. To illustrate this, consider the fragment below:

Dim xml = New XElement("Books", _
            New XElement("Book", _
                New XAttribute("Title", "Introducing VB 9.0"), _
                New XAttribute("Price", "0.00"), _
                New XElement("Author", "Bart De Smet")), _
            New XElement("Book", _
                New XAttribute("Title", "Introducing C# 3.0"), _

                New XAttribute("Price", "0.00"), _
                New XElement("Author", "Bart Simpson")))

This piece of code defines the same as the original fragment that uses VB 9.0's Inline XML feature. I'm sure you agree this, compared to the System.Xml code, exposes the XML structure quite fairly well. In fact, the code shown above just has one constructor call at the top level, constructing the "Books" element and specifying the child items. Even more, guess what a call to ToString() returns? Yes, indeed:

image

That's about it for the System.Xml.Linq API right now, feel free to play around with it and let IntelliSense be your guide. You'll find it very easy to create new pieces of XML even using the raw APIs (that is, without Inline XML in case you want to do the work yourself) and to get to the data. But how can we make this even easier by means of language integration? Let's explore. What about this:

Dim xml = <Books>
                      <Book Title="Introducing VB 9.0" Price="0.00">
                          <Author>Bart De Smet</Author>
                      </Book>
                      <Book Title="Introducing C# 3.0" Price="0.00">
                          <Author>Bart Simpson</Author>
                      </Book>
                  </Books>

For Each book In xml.<Book>
    Console.WriteLine("{0} costs {1} and is written by {2}", book.@Title, book.@Price, book.<Author>.Value)
Next

Whoosh, can it be any easier than this? Just iterate over every <Book> in the XML fragment and select some values. That's right: you can use the dot '.' syntax (the child axis) to dive in the XML structure (a <Book> has an <Author>, thus you can write book.<Author>) and the '.@' syntax (the attribute axis) to select attributes. So, the code above prints:

Introducing VB 9.0 costs 0.00 and is written by Bart De Smet
Introducing C# 3.0 costs 0.00 and is written by Bart Simpson

However, there's something that can be improved in the code above: writing it. Take a look at the IntelliSense:

image

Although a few syntax elements are outlined, there's not much help from the IDE at this stage of the game. That's because the IDE doesn't have information about the XML schema, so how to solve this? The answer, again, is pretty simple: import an XML schema, just like you import a CLR namespace. But before we can do se, we need to create the schema first. An easy way to do this, is by copying the XML fragment straight from the code to an XML file in Visual Studio. Then go to XML, Create Schema:

image

Next, copy the generated schema to the Clipboard, add new item of type XML Schema to the solution, named "VB9Demo.xsd":

image

Copy in the XSD schema that's still on the clipboard and make sure to add the targetNamespace attribute:

image

Save the schema file and go back to the code file and add the following import on top of the code:

Imports <xmlns="http://tempuri.org/VB9Demo">

As you'll see while typing, IntelliSense pops up and helps you a bit:

image

 Now, when you start to use the xml variable, IntelliSense will be so kind to help you a bit:

image 

and

image 

Notice it's also possible to denote an XML namespace by using the following:

Imports <xmlns:ns="http://tempuri.org/VB9Demo">

See the :ns part in the Imports statement above? Now you can use <Books>, <Book> and <Author> if you prefix these with ns:, just as in plain XML. If you don't use a prefix, the schema will be considered to be the default one. A final note on IntelliSense for XML: in VB 9.0 this is limited to XML variables that have been constructed already and that have a known namespace in place. For example, when writing a piece of Inline XML, you won't get IntelliSense. This is something the team is looking into for a subsequent release but I think all of this magic is already very very powerful (and you might want to type the XML pieces in a regular XML editor - like Visual Studio itself - that's aware of the schema you're using, so you get IntelliSense when writing the XML; finally you can copy the result right into your code).

There's one operator I didn't mention yet, that's the ... operator (the descendant axis):

For Each author In xml...<Author>
    Console.WriteLine(author.Value)
Next

This will look for all <Author> tags no matter how deep these are nested in the XML structure, which is certainly easier than having to traverse the XML tree manually or using the '.' syntax.

If you think all of this is already very cool on its own, wait for the next post in this series where we'll cover LINQ, including the combination with XML features in VB 9.0 (a.k.a. the return of the <% ... %>).

Happy coding!

Del.icio.us | Digg It | Technorati | Blinklist | Furl | reddit | DotNetKicks

Filed under:

Comments

# re: Visual Basic 9.0 Feature Focus - XML Support

Tuesday, September 04, 2007 1:30 AM by TraumaPony

Woah, nice. I wish C# 3.0 had this.

# 7 Links Today (2007-09-04)

Tuesday, September 04, 2007 8:20 AM by 7 Links Today (2007-09-04)

Pingback from  7 Links Today (2007-09-04)

# VB 9.0 Feature Focus

Wednesday, September 05, 2007 6:50 PM by Nick's .NET Travels

In my previous post I commented that VB is coming of age in Visual Studio 2008 with better support for

# New Features of Visual Basic 9 Article Series

Thursday, September 27, 2007 5:47 AM by Walter Stiers - Academic Relations Team (BeLux)

In a series of 15 posts, Bart De Smet explores several of the new features in Visual Basic 9 . These

# Extension Methods in Windows PowerShell

Thursday, October 11, 2007 3:31 PM by Elan Hasson's Favorite Blogs

You&#39;ve probably already heard about this new feature in .NET 3.5: extension methods. If not, check

# simply24 &raquo; Blog Archive &raquo; Visual Basic 9.0 Feature Focus - XML Support

Pingback from  simply24  &raquo; Blog Archive   &raquo; Visual Basic 9.0 Feature Focus - XML Support

# http://community.bartdesmet.net/blogs/bart/archive/2007/09/04/visual-basic-9-0-feature-focus-xml-support.aspx

# Recap of European Launch Events for Visual Studio 2008 (Amanda Silver)

Monday, March 24, 2008 4:44 PM by The Visual Basic Team

Last week I had the privilege of speaking in Lisbon, Portugal &amp; Birmingham, England at launch events

# MSDN Blog Postings &raquo; Recap of European Launch Events for Visual Studio 2008 (Amanda Silver)

Pingback from  MSDN Blog Postings  &raquo; Recap of European Launch Events for Visual Studio 2008 (Amanda Silver)

# ヨーロッパでの Visual Studio 2008 発表イベントの要約 (Amanda Silver)

Monday, June 09, 2008 11:42 PM by The Visual Basic Team

先週、 ポルトガルのリスボン と イギリスのバーミンガム での Visual Studio 2008 の発表イベントで講演する機会がありました。どちらも熱狂的な雰囲気に包まれていたのは、今回の Visual

# VB 9.0 Feature Focus – Link Collection

Saturday, August 09, 2008 7:16 AM by B# .NET Blog

Collecting a few of my posts for easy quick reference: Visual Basic 9.0 Feature Focus – Introduction