Using Literal XML with Embedded Expressions in VB9

Introduction

I spent the week of April 13th in Redmond at the MVP Summit. If you don't know, MVP stands for Most Valuable Professional. One usually becomes and MVP by nomination and then having acquired some unknown amount of community kudos. For instance, lots of blogging and voluntarily helping people in newsgroups might get you there eventually. So, the MVP Summit is a way for Microsoft to thank MVPs for their free contributions, continue to foster affinity with these non-Microsoft employees, and provide MVPs with an insider's look at upcoming features. Thanks, Microsoft.

I have to tell you I was shocked! Shocked at the few very vocal Visual Basic MVPs who sounded like whiiiinnnnneeeerrrrs. (You know who you are.) The gist of it was the people don't treat VB programmers like real programmers or at least on a par with, say, C# programmers. They were right. VB contractors make less than C# contractors in general. But, this is not Microsoft's fault, folks. VB can be a tough, gritty language capable of solving any problem that C# can solve, but there is an underlying problem and it lives in the VB community itself.

Many VB programmers are holding onto old VB6 and the VB6 ways of doing things; consequently, there is no room for new articles, new books, or any reason to really learn anything new. So, if VB is the poor cousin, it's our fault. Personally, I know VB is just as good a language as any out there—well, VB9 anyway. To demonstrate that, this article crams seven cool and a bit complicated—if it's your first time seeing them—features into an 80-line sample program.

In this article, you will get a chance to explore LINQ to SQL, generic delegates, literal XML with embedded LINQ expressions, attributes, and Lambda expressions. (Did I say in 80 lines of code?) In fact, even C# can't do literal XML, which is way cool. So, if you know a holdout in VB6 or someone doing things the same old way, feel sorry for them because these features or too cool, too fun, and promote way too much productivity to ever go back.

Previewing the Technology Usage

The basic setup here is that a lot of data exists in databases. This data is generally read from a database, converted to some form or another, changes are made, and then the data is written back to the database. Sometimes, the data is converted to something highly transmittable, such as text/XML.

In the example in Listing 1, you will see just how easy it is to initialize database entities—classes that map to a database table—with LINQ to SQL, and how with literal XML with embedded expressions can be used to transform the entities into any shape XML tree you need. The supporting cast is comprised of Lambda expressions, generic delegates, and attributes.

Listing 1: An 80-line sample program that uses a lot of cool new capabilities provided by VB9 to do some powerful stuff.

Imports System.Data.Linq
Imports System.Data.Linq.Mapping
Imports System.Xml.Linq
Module Module1

   Sub Main()

      Dim ConvertToXML As Func(Of List(Of Shipper), String) = _
         Function(shippers) (<Shippers>
            <%= From shipper In shippers _
               Select <Shipper ShipperID=<%= shipper.ShipperID %>
                  <%= shipper.CompanyName %>>
               <Phone><%= shipper.Phone %></Phone></Shipper> %>
         </Shippers>).ToString()

      Dim northwind As Northwind = New Northwind
      Console.WriteLine(ConvertToXml(northwind.Shippers.ToList()))
      Console.ReadLine()

   End Sub
End Module


Public Class Northwind
   Inherits DataContext
   Private Shared ReadOnly connectionString As String = _
      "Data Source=BUTLER;Initial Catalog= _
       Northwind;Integrated Security=True"

   Public Sub New()
      MyBase.New(connectionString)
   End Sub

   Public ReadOnly Property Shippers() As Table(Of Shipper)
      Get
         Return Me.GetTable(Of Shipper)()
      End Get
   End Property

End Class


<Table(Name:="Shippers")> _
Public Class Shipper

   Private _shipperID As Integer
   <Column(Storage:="_shipperID")> _
   Public Property ShipperID() As Integer
      Get
         Return _shipperID
      End Get
      Set(ByVal Value As Integer)
         _shipperID = Value
      End Set
   End Property

   Private _companyName As String
   <Column(Storage:="_companyName")> _
   Public Property CompanyName() As String
      Get
         Return _companyName
      End Get
      Set(ByVal Value As String)
         _companyName = Value
      End Set
   End Property

   Private _phone As String
   <Column(Storage:="_phone")> _
   Public Property Phone() As String
      Get
         Return _phone
      End Get
      Set(ByVal Value As String)
         _phone = Value
      End Set
   End Property
End Class

Can you spot the technology usage? The Shipper class is an object relational map to the Northwind Shippers table. The Table Attribute identifies the underlying table and the ColumnAttribute identifiers the related column. The Northwind class inherits from DataContext and all you need is the connection string and LINQ to SQL is able to read and write to the database with very little code.

Using Literal XML with Embedded Expressions in VB9

ConvertToXML is a generic delegate that accepts a generic List of Shipper objects and returns a (XML) string. The keyword Function(shippers) signals that you are using a Lambda expression, and <Shippers> is the opening tag of your literal XML. Yep, XML is a valid data type in VB9. The data type of the literal XML is XElement (or XAttribute) from System.Xml.Linq depending on whether the XML is an element or an attribute. The literal values are input arguments to the constructors for these types. When the compiler sees the embedded expression <%= %>, it executes that bit of code and that also is an argument to the appropriate element types constructor.

The generic delegate, Lambda expression, literal XML, and nested LINQ query statement are doing a lot. The From clause defines a range variable shipper. The range value shipper is used in the embedded expressions to obtain the element and attribute values for the XML. The Select statement of the query is actually projecting a new type, literal XML. Finally, the whole XML/LINQ expression is wrapped in parentheses and ToString returns the XML result. Whew! The output from the sample is shown in Listing 2.

Listing 2: The output from Listing 1 is XML.

<Shippers>
   <Shipper ShipperID="1">Speedy Distressed
      <Phone>(503) 555-9831</Phone>
   </Shipper>
   <Shipper ShipperID="2">United Package
      <Phone>(503) 555-3199</Phone>
   </Shipper>
   <Shipper ShipperID="3">Federal Shipping
      <Phone>(503) 555-9931</Phone>
   </Shipper>
</Shippers>

Summary

Last night I heard a Sea World commercial. The tag line was "I believe that fun is a renewable resource". That tagline made me want to go back to Sea World, but it also resonated with me because I believe it, too. Software is supposed to be fun. And these new features are a lot of fun.

VB6 was great in its day, but there is a whole lot more fun out there just waiting to be explored and used. With Lambda expressions, LINQ to SQL, literal XML and embedded expressions, and generic delegates VB9 is not only not your father's Oldsmobile, it may very well be your son's Tesla Roadster—check out http://www.teslamotors.com/. (Sorry; I couldn't resist.)

About the Author

Paul Kimmel is the VB Today columnist for www.codeguru.com and has written several books on object-oriented programming and .NET. Check out his upcoming book LINQ Unleashed for C# due in July 2008. Paul Kimmel is an Application Architect for EDS. You may contact him for technology questions at pkimmel@softconcepts.com.

If you are interested in joining or sponsoring a .NET Users Group, check out www.glugnet.org. Glugnet opened a users group branch in Flint, Michigan in August 2007. If you are interested in attending, check out the www.glugnet.org web site for updates.

Copyright © 2008 by Paul T. Kimmel. All Rights Reserved.



Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • As a result of corporate expansions, mergers, and acquisitions, the teams and technologies that support an organization's IT service management (ITSM) practices can over time become somewhat dispersed. Supporting an organization's strategic objectives, and providing consistent and quality IT support is essential, but this can be challenging where disconnected support environments exist. While physically centralizing support is not always possible, nor is it always desirable, delivering a consistent and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds