Embed Code and Avoid Underscores in Your Multiline Strings

Published 23 October 07 12:03 PM

One of the things I most dearly missed from FoxPro when I moved to VB.NET was the ability to easily dump a bunch of text (multi-line string literals) into the editor easily and embed code (text-merge). FoxPro has a keyword TEXT...ENDTEXT for this and I used to use it all the time. In VB it gets pretty darn ugly with any large amount of text because you have to concatenate string literals with your code and use underscores for readability.

  Dim oldWay = "this is a string" & vbCrLf & _

               "with formatting" & vbCrLf & _

               "and stuff" & vbCrLf & _

               "look ma, underscores" & vbCrLf & _

               "         tabs too"

 

  MsgBox(oldWay)

Not any more. With Visual Basic 9's built in XML literals support we can now easily write a bunch of text directly into the editor:

         Dim newWay = <string>

this is a string

with formatting

and stuff

look ma, no underscores!!!

            tabs too

                </string>

 

        MsgBox(newWay.Value)

The text formatting is preserved as well. All you have to do is get the .Value of the XElement, which is the string literal. As you can see this is much cleaner than what we're used to. And if you still like to see your string literals in the default reddish color, you can easily change the color settings for VB XML literals in Tools --> Options --> Environment --> Fonts and Colors, then select "VB XML Text" and set the custom color to RGB(163,21,21). Here's another example, some SQL query text (now with the reddish color): 

        Dim query = <query>

SELECT Customers.*, Orders.OrderDate

FROM Customers

    INNER JOIN Orders ON Orders.CustomerID = Customers.CustomerID

WHERE Customers.CustomerID = @CustomerID

                    </query>

 

        Dim cmd As New SqlCommand(query.Value)

        cmd.Parameters.AddWithValue("@CustomerID", id)

Now here's where it gets fun. You can also embed expressions into these literals with the <%= syntax. This means you can do any kind of text merging much cleaner than ugly concatenation of strings with code or use of String.Format especially as the size of the text increases. Here's some simple examples:

        Dim simple = <string>

This is a simple text merge example:

Hello, <%= Environment.UserName %>

                     </string>

 

        MsgBox(simple.Value)

 

 

        Dim controls = <string>

There are the following controls on this form:

<%= From item In Me.Controls Select item.ToString & vbCrLf %></string>

 

        MsgBox(controls.Value)

Calvin has some good examples here and here on how to generate scripts dynamically, but here's one that uses a simple code generation pattern. 

Private Sub CreateClass()

        Dim CustomerSchema As XDocument = XDocument.Load(CurDir() & "\customer.xsd")

 

        Dim fields = From field In CustomerSchema...<xs:element> _

                     Where field.@type IsNot Nothing _

                     Select Name = field.@name, Type = field.@type

 

 

        Dim customer = <customer>

Public Class Customer

    <%= From field In fields Select <f>    

        Private m_<%= field.Name %> As <%= GetVBPropType(field.Type) %></f>.Value %>

 

        <%= From field In fields Select <p>    

        Public Property <%= field.Name %> As <%= GetVBPropType(field.Type) %>

            Get

                Return m_<%= field.Name %> 

            End Get

            Set(ByVal value As <%= GetVBPropType(field.Type) %>)

                m_<%= field.Name %>  = value

            End Set

        End Property</p>.Value %>                       

End Class</customer>

 

        My.Computer.FileSystem.WriteAllText("Customer.vb", customer.Value, _

False, System.Text.Encoding.ASCII)

 

    End Sub

 

    Private Function GetVBPropType(ByVal xmlType As String) As String

        Select Case xmlType

            Case "xs:string"

                Return "String"

            Case "xs:int"

                Return "Integer"

            Case "xs:decimal"

                Return "Decimal"

            Case "xs:boolean"

                Return "Boolean"

            Case "xs:dateTime", "xs:date"

                Return "Date"

            Case Else

                Return "'TODO: Define Type"

        End Select

    End Function

I hope this gives you some good ideas on what you can do with XML Literals. You literally (pun intended ;-)) don't have to use them to produce XML, you can use them to produce any text-based output.

Enjoy,
-B

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Josh Stodola said on October 23, 2007 4:41 PM:

I have rug burn on my chin because of this post!

I simply can NOT wait for the release, this is gonna be so awesome.

# Beth Massi said on October 23, 2007 5:39 PM:

Josh,

LOL! You can give it a try right now (Beta 2) if you have an extra machine or Virtual Machine laying around: http://msdn2.microsoft.com/en-us/vstudio/aa700831.aspx

And congrats on starting your blog! ;-)

# Josh Stodola said on October 24, 2007 9:53 AM:

I'd love to give it a try but I dont an extra machine laying around.  Ok, well I do, but it is an antique unworthy of any version of VS!!

Thanks :)

I might ask around at work and see if there is a "playground" machine I can have for a while.

# Billy Hollis said on October 24, 2007 11:50 AM:

Beth, I'm stealing, er, uh, borrowing some of these examples for my "What's new in VB9" talk at DevConnections Las Vegas. Your name will be mentioned prominently.

# Beth Massi said on October 24, 2007 12:08 PM:

Hi Billy!,

For you, anything! ;-) Ping me directly if you need any more demos, decks, etc. I'll be speaking at Silicon Valley code-camp this weekend and then QCon in SF Nov 9th so I've pulling demos together this week.

-B

# Manos Kelaiditis' Weblog said on October 25, 2007 2:47 AM:

Ένα από τα νέα χαρακτηριστικά της VB.NET είναι η υποστήριξη XML Literals. Πρόκειται για τη δυνατότητα

# Beth Massi - Sharing the goodness that is VB said on October 26, 2007 4:09 PM:

A couple quick tips here when using XML literals in your Visual Basic programs. #1: I've started using

# Sven Groot said on October 27, 2007 5:19 AM:

Hi Beth,

XML literals are one of my favourite new features in VB9, really looking forward to using this in a real product.

I'm not sure I like it for multiline strings though, because of the break in indentation. It's still a pretty cool idea though. :)

# The Visual Basic Team said on November 1, 2007 3:08 PM:

We just released a new set of How-Do-I videos in our LINQ series on LINQ to XML in Visual Basic. These

# Beth Massi - Sharing the goodness that is VB said on November 2, 2007 12:02 PM:

We just released a new set of How-Do-I videos in our LINQ series on LINQ to XML in Visual Basic. These

# Beth Massi - Sharing the goodness that is VB said on December 6, 2007 9:26 PM:

I've mentioned before that you can use XML literals in VB 9 to do text merging so I figured it should

# Noticias externas said on December 6, 2007 10:01 PM:

I&#39;ve mentioned before that you can use XML literals in VB 9 to do text merging so I figured it should

# Noticias externas said on February 11, 2008 5:06 PM:

A while back I showed a very simple way you could use XML Literals to generate code. In my previous life

# Nishtha said on May 8, 2008 9:18 AM:

Hi

Can you please let us know if VB can read a text file of around 90 MB file size and process relevant data out of it.

Thanks

Nishtha

# Robin Lewis said on December 5, 2008 11:24 AM:

So why did it take Microsoft 16 years to implement a form of multi-line strings? (Working from the original May 1991 release date for VB 1.0, Comdex/Windows World trade show in Atlanta, Georgia) The original bourne shell released with Unix Version 7 (in 1977) had here-documents.

# vbuser said on February 20, 2009 3:02 PM:

should be able to

dim s as string

s = |

This is

a

multiline

string|

VB and LotusScript supported this simple method.  Using the suggested xml text is buggy.  You will get errors in Studio 08 depending on what is in  the text (and its all text with no <> substitutions).  I can't use the suggestion above because it only sometimes works and isn't predictable.

# Beth Massi said on February 27, 2009 3:22 PM:

Hi vbuser,

Can you show me an example of text that won't work?

Thanks,

-B

# Dan Neuman said on March 25, 2009 4:38 PM:

Beth,

I really like this.  I used the Text/EndText in VFP to write my SQL strings and it would be easy to copy commands between VFP and Query Analyzer.

Using your new construct, I am having problems with the following code where the visual studio compiler is giving me errors.  It appears to not like my "less than" sign in the middle of the string... any ideas?

       Dim sProblem = <myxml>select * from detailinfo where isnull(FaxedDate, '1900-1-1') < '1901-1-1'</myxml>

# Beth Massi said on March 25, 2009 4:58 PM:

Hi Dan,

Remember that this is XML. All XML parsing rules apply so you cannot place < or > characters in the element. Here is a list of XML Entities that are reserved: http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references#Predefined_entities_in_XML

However you can still render them by using the entity's name instead. In your example it would be:

Dim sProblem = <myxml>select * from detailinfo where isnull(FaxedDate, '1900-1-1') &lt; '1901-1-1'</myxml>

MsgBox(sProblem.Value)

HTH,

-B

# Dan Neuman said on March 26, 2009 2:52 PM:

Beth,

Thank you for the quick response.  Just couple more questions, my "coding police" wont let me use variants in my declarations.  What is the datatype that is used for this?  Also, as I try this in a few of my projects, I get very long error messages about system.xml is not available, eventhough it is listed at the top of the module.

dim sProblem as ???

# Beth Massi said on March 26, 2009 3:28 PM:

Hi Dan,

You're using Visual Studio 2008 and Visual Basic 9 so the compiler will automatically infer the type of the variable. This is specified by Option Infer ON (which is the default in new projects). You should have Option Strict, Explicit and Infer all ON. Your statement above is not an Object (no variants in .NET ;-)) it is inferred by the compiler and still is strongly typed. Just hover over the variable and you should see the type of it. In this case it is an XElement. But you can be explict and say Dim sProblem as XElement = ... if that appeases the gods. It's just more typing ;-)

HTH,

-B

# Dan Neuman said on March 26, 2009 4:32 PM:

ok, last question I hope.  As I try this on a project that was upgraded from VS2005 to VS2008, I get an error message that reads "XML literals and XML axis properties are not available.  Add references to System.xml, System.xml.linq, and system.core.

System.xml is already part of the project, and it won't allow me to add system.xml.linq.  any ideas what I am missing?

# Beth Massi said on March 26, 2009 4:43 PM:

Hi Dan,

You'll need to set the framework target to 3.5 first.

See:

http://msdn.microsoft.com/en-us/library/07bysfz2.aspx

and

http://msdn.microsoft.com/en-us/library/bb398197.aspx

HTH,

-B

Leave a Comment

(required) 
(optional)
(required) 

About Beth Massi

Beth is a Program Manager on the Visual Studio Community Team at Microsoft and is responsible for producing and managing content for business application developers, driving community features and team participation onto MSDN Developer Centers (http://msdn.com), and helping make Visual Studio one of the best developer tools in the world. She also produces regular content on her blog (http://blogs.msdn.com/bethmassi), Channel 9, and a variety of other developer sites and magazines. As a community champion and a long-time member of the Microsoft developer community she also helps with the San Francisco East Bay .NET user group and is a frequent speaker at various software development events. Before Microsoft, she was a Senior Architect at a health care software product company and a Microsoft Solutions Architect MVP. Over the last decade she has worked on distributed applications and frameworks, web and Windows-based applications using Microsoft development tools in a variety of businesses. She loves teaching, hiking, mountain biking, and driving really fast.
Page view tracker