Using XML literals lets you write XML directly within your Visual Basic code providing the same structure and layout as the resulting XML.. Again, this is quite similar to the way theXDo
Trang 1foreach (XElement el in xmlTree)
On the surface, LINQ to XML looks intimidating, but this and the previous three chapters should have
dispelled that vicious rumor Hopefully, as you started working your way through this chapter, you
quickly realized that it really wasn’t as bad as you thought Sure, working with annotations, events, andaxes can be tough, but the purpose of this chapter was to show you that working with them also can bedelightful and downright fun
You first examined functional construction and the important role it plays in LINQ to XML Functionalconstruction provides the capability to easily and efficiently construct an XML document within a singlestatement Then you saw how to add annotations to elements and attributes in an XML tree using the
AddAnnotationmethod, and how to read annotations once they are applied
You explored LINQ to XML axis methods, which provide the capability to quickly and efficiently query
an XML tree to find elements and attributes and return their values Knowing how to use these is lutely necessary to understanding and writing query expressions
abso-Finally, you saw how to stream XML documents using LINQ to XML and the benefits that streaming
provides, such as managing memory and controlling the size of your XML documents
Chapter 9, the last chapter in this section, focuses on LINQ to XML in Visual Basic NET
177
Trang 3LINQ to XML and V isual
Basic NET
Visual Basic NET wasn’t left behind when it comes to working with LINQ to XML Visual
Basic provides profound support for LINQ to XML through XML literals and XML
Axis properties
This chapter focuses on the LINQ to XML differences that apply to Visual Basic NET You’ll explore
the following topics in this chapter:
You have to agree that LINQ to XML is powerful and flexible One of the things you have seen is
the capability to call LINQ APIs directly, but what you are about to see makes LINQ to XML even
better In Visual Basic, you can declare XML literals and write XML directly in your code And you
also can access XML Axis properties from within your code
However, it is important to understand what XML literals are so that you can have a better
appreciation, as well as for creating XML
Trang 4Overview of XML Literals
An XML Literal is a piece of XML, such as a complete XML document or XML fragment, that is
typed directly into the source code of a Visual Basic NET module without the use of quotation
marks Using XML literals lets you write XML directly within your Visual Basic code providing the
same structure and layout as the resulting XML This means that you can create XML documents
and fragments easily and efficiently right in your code
XML literal syntax is a representation of the LINQ to XML objects, with Visual Basic compiling the literals
into LINQ to XML objects This functionality is provided via the LINQ to XML object model, which lets
you create and work with XML easily
To get a feel for XML Literals, create a new Windows Forms Visual Basic project in Visual Studio
When the project is created, add a reference to theSystem.Xml.Linqnamespace Open the form in
design view and add a few buttons and a text box Set the Multiline property of the text box toTrue
and size the text box so that you can easily view an XML document or fragment
Next, double-click on the form to view the code behind it, and add the following statement in the
declarations section:
Imports System.Xml.Linq
Next, behind button1, add the following highlighted code Pay attention to what happens as you type
the code for the XML element
Private Sub Button1_Click(ByVal sender As System.Object,
Slick, isn’t it? The XML you typed into the Visual Basic code looks exactly like the XML fragment that
appears in the text box when you run the application and click button1:
Trang 5You can even create XML documents using XML literals To do so, simply add the highlighted code to
your XML from the previous example:
Dim emp As XElement = _
To fix this, simply change theXElementto anXDocumentas highlighted here:
Dim empDoc As XDocument = _
encoun-Depending on the XML literal, the XML literal will be translated into calls to one or several
constructors At the least, it will be converted to a call to theXElementconstructor, and if your XML eral contains attributes, then there will be calls to theXAttributeconstructor as well If your XML literalcontains version instructions, it will be translated into a call to theXProcessingInstructionconstructor.Each class, such as theXElementandXAttribute, has an overloadedNewconstructor These constructorsare called for each type found, meaning that the XML literal will be translated into a call and passed
lit-to the corresponding construclit-tor For example, if you have an element that contains two attributes, the
XElementconstructor will be called once and theXAttributeconstructor will be called twice
Now that you understand how XML literals work, let’s look at some examples of creating XML
The following example is taken from the first example in this chapter and illustrates the simple way
to create XML It uses theXElementclass to create a simple XML fragment containing employee
information
You should be quite familiar with theXElementclass by now It’s used to represent an XML element
The only difference here is the capability to use it to create XML literals in Visual Basic For example,
the following code creates an XML fragment in Visual Basic NET Notice the exclusion of any quotes
The XML is typed directly into the source code of the project
181
Trang 6Dim emp As XElement = _
The following example creates an XML document with a comment and version information Again, this is
quite similar to the way theXDocumentclass was used in previous chapters, but it’s used in this example
There is so much more that XML literals can do, such as using embedded expressions Visual Basic
supports the concept of embedded expressions These expressions have the following syntax:
<%=expression%>
With Visual Basic you can place embedded expressions directly within your XML literals These
expressions are then evaluated at runtime
For example, the following code defines two variables, one that contains the employee ID, and the
other that contains the employee name These two variables are then used as embedded expressions
in the creation of the XML literal to specify the value of theempIDattribute value and theFirstName
element value
Dim empID As Integer
Dim empName As String
empID = 1
empName = "Scott"
Dim emp As XElement = _
<Employee empID=<%= empID %>>
Trang 7When this code is run, you’ll get the following output:
Dim empID As String
Dim empName As String
This can be taken one step further by including values for the name/value pair, like this:
Dim empID As String
Dim empName As String
There are a couple of noteworthy items of which you should be aware First, be careful how you use
Option Strictin this scenario.Option Strictwill cause the compiler to check each type to ensure
that it has widened to the required type This applies to everything except the root element of an XML
document If you leaveOption Strictoff, expressions of type Object can be embedded, in which case
their type is verified at runtime
183
Trang 8Second, you will probably run into situations where content is optional In those cases,
embedded expressions that containNothingare ignored Thus, there is no need to check that
the values of elements or attributes are notNothingas you use XML literals In other words, required
values such as element and attribute names cannot beNothing, but empty embedded expressions are
ignored Sweet
Embedding Queries
The fact that you can embed expressions within your XML literal should tell you that you can also
embed queries within your XML literal When queries are embedded within the XML literal, all
ele-ments returned by the query are added to the XML This lets you create and add dynamic content to
your XML literal
In the following example, a standard LINQ query is embedded in the XML literal, which will create an
XML tree based on the value returned from the query
Dim emp As XElement = _
<Employee>
<%= From con in Contact
Select <name><%= con.FirstName %></name>
%>
</Employee>
That gives you an idea of what is possible when LINQ queries are embedded in XML literals However,
take it a step further and add an attribute to the XML Modify the XML as highlighted:
Dim emp As XElement = _
<Employee>
<%= From con in Contact
Select <name id=<%= con.ContactID %>><%= con.FirstName %></name>
%>
</Employee>
Now you have a good understanding of how easy it is to dynamically create and add content
to your XML
Understanding Whitespace in Visual Basic XML Literals
Only significant whitespace is included in an XML literal by the Visual Basic compiler when a LINQ to
XML object is created Any insignificant whitespace is ignored
To illustrate how whitespace is used, add the following code to the click event of one of the buttons
on your form:
Dim empID As String
Dim empName As String
empID = "ID"
empName = "FirstName"
Dim emp As XElement = _
184
Trang 9Notice all of the whitespace to the left of ‘‘Scott’’ and to the left of the<FirstName>closing tag.
The output is like this because the inner element,<FirstName>, contains significant whitespace
and the output text, while the outer element,<Employee>, contains insignificant whitespace
So, you are probably asking yourself, what is the difference between ‘‘significant’’ and ‘‘insignificant’’
whitespace? Whitespace in XML literals is considered significant when:
❑ It is in an attribute value
❑ It is part of an element’s text content
❑ It is in an embedded expression for an element’s text content
You can add thexml:spaceattribute in the XML element literal, but it won’t change how the compiler
handles the whitespace
Accessing XML
Creating XML is one thing, but accessing it is another, and this section shows you how to do that in
Visual Basic Navigating XML structures in LINQ to XML is quite easy in Visual Basic To illustrate, addanother button to your form and place the following code in its click event:
Dim employee As XElement = _
Trang 10</Employee>
</Employees>
Me.TextBox1.Text = employee <City>.Value
Run the project and click the button The text box should display the following value:
Wellington
Accessing element and attribute values is done through XML axis properties, which provide the
capabil-ity to navigate XML structures These properties use a special syntax that helps access any element and
attribute by specifying XML names within your XML document
Following are the available properties for accessing element and attribute values:
❑ Descendant axis—Returns all the child elements of the specified element regardless
how deep in the hierarchy the child elements are found The preceding example illustrates
this point The<City>element is several nodes deep in the XML fragment but through the
use of the descendant axis property you can easily access the value of that node, as
shown above
Because it doesn’t matter how deep in the hierarchy the element is found, you can use the same
syntax to return the value of the<Title>as well as any other element
❑ Child axis—Returns all the elements that are child elements of the specified element This
prop-erty is used to return all the child elements of a specified element For example:
employee.<FirstName>
❑ Attribute axis—Returns all the attributes of the specified element From the preceding XML
fragment, this property can be used to return theEmpIDattribute of<Employee>node:
Employee.<Employee>.@EmpID
❑ Value—Returns a string containing the object (value) for the first object found in the sequence
It returnsNothingif the sequence is empty As you have seen, this property returns the value of
the specified node(s), such as the value of the<City>element:
employee <City>.Value
❑ Extension indexer—Returns the first element from the sequence To illustrate this property,
modify the XML fragment at the beginning of this section by adding a second employee, as
shown in the following highlighted code:
Dim employee As XElement = _
Trang 11The returned result would beChris The extension indexer is zero-based so had you passed a value of0
to this property, it would have returnedScott
You can also access XML using embedded queries, which you learned about earlier in the chapter In theexample that follows, an XML literal is defined with three names A second XML literal is then created,using an embedded query to access the names from the first XML literal The results of the second XMLliteral are displayed in the text box
Dim employee As XElement = _
<%= From name In employee.<Name> _
Select <FirstName><%= name.Value %></FirstName> _
%>
</Names>
Me.TextBox1.Text = nameTypes.ToString
187
Trang 12Here are the results when this code is executed:
The next example builds on the previous example by including an attribute on each<Name>element in
the first XML literal The second XML literal is also modified, adding the necessary components to the
embedded query to access the attribute as well
Dim employee As XElement = _
<%= From name In employee.<Name> _
Select <Employee ID=<%= name.Value %>><%= name.@empID %></Employee> _
Yes, this example puts the attribute back where it came from, but the purpose of this example is to
illus-trate how to access attributes and how you can utilize query expressions within your XML literals to
manipulate XML
These examples should give you a good idea of how to access XML using XML literals and
query expressions
Loading XML
Loading XML is quite easy You’ll see just how easy in a minute First, open your favorite text editor and
type in the following XML Save it asemployees.xmlin yourWrox\Chapter 9folder
Trang 13To load XML, theXElementclass has aLoadmethod that contains several overloads, one of which
is a path to an XML document The following code shows how to load an element and display
its contents:
Dim emp As XElement = XElement.Load("c:\Wrox\Linq\Chapter9\employees.xml")
Me.Textbox1.Text = emp.ToString
As you know, once you have XML loaded into anXElement, as in the preceding example, you
are free to manipulate and query it Your homework for this chapter is to use a query expression
within an XML literal to return XML containing the ID of the employee along with his
name and title
Manipulating XML Using the Parse Method
There is a method on theXElementclass calledParse, which loads a string containing XML into an
XElement There is an overload on this method that enables you to specify options when parsing the
XML being loaded
In the following example, a string variable is defined and loaded with an XML fragment The
string is then passed to theParsemethod of theXElementclass The additional parameter for
189
Trang 14the load options specifies a value ofNone, meaning that no load options are being specified Load options
are explained shortly
Dim empInfo As String
empInfo = "<Employees><Employee ID=""1""><FirstName>Scott</FirstName>@@ta
❑ None—No options are specified
❑ PreserveWhitespace—Preserve insignificant whitespace during the parsing
of the XML
❑ SetBaseUri—Requests the base URI information from the XmlReader, making it available through
theBaseUriproperty
❑ SetLineInfo—Requests the line information from the XmlReader, making it available through
XObjectproperties
The following example illustrates the use of thePreserveWhitespaceload option Modify the code from
the previous example as follows:
Dim empInfo As String
empInfo = "<Employees><Employee ID=""1""><FirstName>Scott</FirstName>@@ta
Trang 15You can see that all of the insignificant whitespace has been ignored Next, modify the load option
to this:
Dim emp As XElement = XElement.Parse(empInfo, LoadOptions.PreserveWhitespace)
When you run the code now, all the insignificant whitespace is preserved:
<Employees>
<Employee ID="1"> <FirstName> Scott </FirstName></Employee>
</Employees>
Specify multiple load options by using anAndorOroperator, like this:
Dim emp As XElement = XElement.Parse(empInfo, LoadOptions.SetBaseUri And
LoadOptions.SetLineInfo)
These load options can assist you in your manipulation of the XML document, such as controlling howthe whitespace is preserved and tracking the line information for each element in the tree
LINQ to XML V isual Basic Example
This example is going to use the XML documentemployees.xmlthat you created earlier, in the
section ‘‘Loading XML.’’ This example will load that document, manipulate it by making some changes
to the XML tree, and then display the results As a refresher, the contents of the XML document
Trang 16<Employee id="3" Dept="0004" Geek="True">
So, to do this, create a new Visual Basic Windows Forms project When the project is created, add two
buttons and a text box to the form Set the properties of the controls as follows:
Trang 17Next, in theClick()event of the OK button, place the following code:
Dim emp As XElement = XElement.Load("c:\Wrox\Linq\Chapter 9\Employees.xml")
Dim tree As XElement = New XElement("Root", _
From el In emp.Elements() Select el)
’ Load these changes into the first text box
Me.txtResults1.Text = tree.ToString()
’ Next, let’s just grab the first employee
Dim empPart as XElement = (From treePart In _
tree.Eleemnts("Employees") Select treePart).First
The second query produces the following results:
<Employee id="1" Dept="0001" Geek="True">
Trang 18And lastly, the final piece of code modifies the XML document and returns the following results, with
the addition of theEmailAddresselement added to each Employee node:
You’ll notice that each email address node is not populated with data This is on purpose Your
home-work assignment for this chapter is to modify the code to add an email address You don’t need to make
them different Simply insert a default value When you have done that, figure out a way to dynamically
enter an email address using the employee’s first name and last name
Summar y
This chapter focused on the LINQ to XML features in Visual Basic NET, including the capability to create
XML literals and expressions directly within your VB.NET code
194
Trang 19You learned to create XML using XML literals, and how to incorporate expressions and embedded
queries into your XML literals to create the XML you want
From there, the topics of accessing and loading XML were discussed Accessing XML is accomplished
through the XML Axis properties, which enable you to easily and efficiently navigate the XML tree
and retrieve the information you want Loading XML is as simple as calling theLoadmethod on the
XElementclass
You also explored using theParsemethod to manipulate XML It enables you to specify several load
options so that you can manipulate the XML as you parse it For example, you can preserve the
whitespace or track individual element line item information
In the next chapter, the focus turns to working with LINQ to SQL
195