Tải bản đầy đủ (.pdf) (133 trang)

Professional Visual Basic 2010 and .neT 4 phần 4 docx

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (3.66 MB, 133 trang )

356

CHAPTER 9 usiNG xml witH Visual BasiC
In this case, the XmlReader object that is created ignores the white space that it encounters, as well as any
of the XML comments. These settings, once established with the XmlReaderSettings object, are then
associated with the XmlReader object through its Create method.
Traversing XML Using XmlReader
An application can easily use XmlReader to traverse a document that is received in a known format. The
document can thus be traversed in a deliberate manner. You just implemented a class that serialized arrays
of movie orders. The next example takes an XML document containing multiple XML documents of that
type and traverses them. Each movie order is forwarded to the movie supplier via fax. The document is
traversed as follows:
Read root element: <MovieOrderDump>
Process each <FilmOrderList> element
Read <multiFilmOrders> element
Process each <FilmOrder>
Send fax for each movie order here
The basic outline for the program’s implementation is to open a file containing the XML document to parse
and to traverse it from element to element:
Dim myXmlSettings As New XmlReaderSettings()
Using readMovieInfo As XmlReader = XmlReader.Create(fileName, myXmlSettings)
readMovieInfo.Read()
readMovieInfo.ReadStartElement("MovieOrderDump")
Do While (True)
'****************************************************
'* Process FilmOrder elements here *
'****************************************************
Loop
readMovieInfo.ReadEndElement() ' </MovieOrderDump>
End Using
Code snippet from FilmOrdersReader2


The preceding code opened the file using the constructor of XmlReader, and the End Using statement takes
care of shutting everything down for you. The code also introduced two methods of the XmlReader class:
➤ ReadStartElement(String) — This verifies that the current node in the stream is an element
and that the element’s name matches the string passed to
ReadStartElement. If the verification is
successful, then the stream is advanced to the next element.
➤ ReadEndElement() — This verifies that the current element is an end tab; and if the verification is
successful, then the stream is advanced to the next element.
The application knows that an element, <MovieOrderDump>, will be found at a specific point in the
document. The ReadStartElement method verifies this foreknowledge of the document format. After all
the elements contained in element <MovieOrderDump> have been traversed, the stream should point to the
end tag </MovieOrderDump>. The ReadEndElement method verifies this.
The code that traverses each element of type
<FilmOrder> similarly uses the ReadStartElement and
ReadEndElement methods to indicate the start and end of the <FilmOrder> and <multiFilmOrders>
elements. The code that ultimately parses the list of movie orders and then faxes the movie supplier (using
the FranticallyFaxTheMovieSupplier subroutine) is as follows:
Private Sub ReadMovieXml(ByVal fileName As String)
Dim myXmlSettings As New XmlReaderSettings()
Dim movieName As String
Dim movieId As String
Dim quantity As String

XmlReader.Create(fileName, myXmlSettings)
Simpo PDF Merge and Split Unregistered Version -
'position to first element
readMovieInfo.Read()
readMovieInfo.ReadStartElement("MovieOrderDump")
Do While (True)
readMovieInfo.ReadStartElement("FilmOrderList")

readMovieInfo.ReadStartElement("multiFilmOrders")

'for each order
Do While (True) readMovieInfo.MoveToContent()
movieId = readMovieInfo.GetAttribute("filmId")
readMovieInfo.ReadStartElement("FilmOrder")

movieName = readMovieInfo.ReadElementString()
quantity = readMovieInfo.ReadElementString()
readMovieInfo.ReadEndElement() ' clear </FilmOrder>

FranticallyFaxTheMovieSupplier(movieName, movieId, quantity)

' Should read next FilmOrder node
' else quits
readMovieInfo.Read()
If ("FilmOrder" <> readMovieInfo.Name) Then
Exit Do
End If
Loop
readMovieInfo.ReadEndElement() ' clear </multiFilmOrders>
readMovieInfo.ReadEndElement() ' clear </FilmOrderList>
' Should read next FilmOrderList node
' else you quit
readMovieInfo.Read() ' clear </MovieOrderDump>
If ("FilmOrderList" <> readMovieInfo.Name) Then
Exit Do
End If
Loop
readMovieInfo.ReadEndElement() ' </MovieOrderDump>

End Using
End Sub
Code snippet from FilmOrderReader2
The values are read from the XML file using the ReadElementString and GetAttribute methods.
Notice that the call to GetAttribute is done before reading the FilmOrder element. This is because the
ReadStartElement method advances the location for the next read to the next element in the XML file.
The MoveToContent call before the call to GetAttribute ensures that the current read location is on the
element, and not on white space.
While parsing the stream, it was known that an element named
name existed and that this element
contained the name of the movie. Rather than parse the start tag, get the value, and parse the end tag, it was
easier to get the data using the ReadElementString method.
The output of this example is a fax (left as an exercise for you). The format of the document is still verified
by
XmlReader as it is parsed.
The
XmlReader class also exposes properties that provide more insight into the data contained in
the XML document and the state of parsing: IsEmptyElement, EOF, HasAttributes, and
IsStartElement.
.NET CLR-compliant types are not 100 percent interchangeable with XML types, so ever since the .NET
Framework 2.0 was introduced, the new methods it made available in the
XmlReader make the process of
casting from one of these XML types to .NET types easier.
XML Stream-Style Parsers

357
Simpo PDF Merge and Split Unregistered Version -
358

CHAPTER 9 usiNG xml witH Visual BasiC

Using the ReadElementContentAs method, you can easily perform the necessary casting required:
Dim username As String = _
myXmlReader.ReadElementContentAs(GetType(String), DBNull.Value)
Dim myDate As DateTime = _
myXmlReader.ReadElementContentAs(GetType(DateTime), DBNull.Value)
In addition to the generic ReadElementContentAs method, there are specific ReadElementContentAsX
methods for each of the common data types; and in addition to these methods, the raw XML associated
with the document can also be retrieved, using ReadInnerXml and ReadOuterXml. Again, this only
scratches the surface of the XmlReader class, a class quite rich in functionality.
Handling Exceptions
XML is text and could easily be read using mundane methods such as Read and ReadLine. A key feature of
each class that reads and traverses XML is inherent support for error detection and handling. To demonstrate
this, consider the following malformed XML document found in the file named Malformed.xml:
<?xml version="1.0" encoding="IBM437" ?>
<FilmOrder FilmId="101", Qty="10">
<Name>Grease</Name>
<FilmOrder>
Code snippet from FilmOrdersReader2
This document may not immediately appear to be malformed. By wrapping a call to the method you
developed (ReadMovieXml), you can see what type of exception is raised when XmlReader detects the
malformed XML within this document as shown in Sub Main(). Comment out the line calling the
MovieManage.xml file, and uncomment the line to try to open the malformed.xml file:
Try
'ReadMovieXml("MovieManage.xml")
ReadMovieXml("Malformed.xml")
Catch xmlEx As XmlException
Console.Error.WriteLine("XML Error: " + xmlEx.ToString())
Catch ex As Exception
Console.Error.WriteLine("Some other error: " + ex.ToString())
End Try

Code snippet from FilmOrdersReader2
The methods and properties exposed by the XmlReader class raise exceptions of type System.Xml
.XmlException
. In fact, every class in the System.Xml namespace raises exceptions of type XmlException.
Although this is a discussion of errors using an instance of type XmlReader, the concepts reviewed apply to
all errors generated by classes found in the System.Xml namespace. The XmlException extends the basic
Exception to include more information about the location of the error within the XML file.
The error displayed when subroutine
ReadMovieXML processes Malformed.xml is as follows:
XML Error: System.Xml.XmlException: The ',' character, hexadecimal value 0x2C,
cannot begin a name. Line 2, position 49.
The preceding snippet indicates that a comma separates the attributes in element
<FilmOrder FilmId=“101”, Qty=“10“>. This comma is invalid. Removing it and running the code again
results in the following output:
XML Error: System.Xml.XmlException: This is an unexpected token. Expected
'EndElement'. Line 5, position 27.
Again, you can recognize the precise error. In this case, you do not have an end element, </FilmOrder>, but
you do have an opening element, <FilmOrder>.
Simpo PDF Merge and Split Unregistered Version -
The properties provided by the XmlException class (such as LineNumber, LinePosition, and Message)
provide a useful level of precision when tracking down errors. The XmlReader class also exposes a level of
precision with respect to the parsing of the XML document. This precision is exposed by the XmlReader
through properties such as LineNumber and LinePosition.
Document Object Model (DOM)
The Document Object Model (DOM) is a logical view of an XML file. Within the DOM, an XML
document is contained in a class named XmlDocument. Each node within this document is accessible and
managed using XmlNode. Nodes can also be accessed and managed using a class specifically designed to
process a specific node’s type (XmlElement, XmlAttribute, and so on). XML documents are extracted from
XmlDocument using a variety of mechanisms exposed through such classes as XmlWriter, TextWriter,
Stream, and a file (specified by a filename of type String). XML documents are consumed by an

XmlDocument using a variety of load mechanisms exposed through the same classes.
A DOM-style parser differs from a stream-style parser with respect to movement. Using the DOM, the
nodes can be traversed forward and backward; and nodes can be added to the document, removed from
the document, and updated. However, this flexibility comes at a performance cost. It is faster to read or
write XML using a stream-style parser.
The DOM-specific classes exposed by
System.Xml include the following:
➤ XmlDocument — Corresponds to an entire XML document. A document is loaded using the Load
or
LoadXml methods. The Load method loads the XML from a file (the filename specified as type
String), TextReader, or XmlReader. A document can be loaded using LoadXml in conjunction
with a string containing the XML document. The
Save method is used to save XML documents.
The methods exposed by
XmlDocument reflect the intricate manipulation of an XML document.
For example, the following creation methods are implemented by this class:
CreateAttribute,
CreateCDataSection, CreateComment, CreateDocumentFragment, CreateDocumentType,
CreateElement, CreateEntityReference, CreateNavigator, CreateNode,
CreateProcessingInstruction, CreateSignificantWhitespace, CreateTextNode,
CreateWhitespace, and CreateXmlDeclaration. The elements contained in the document can be
retrieved. Other methods support the retrieving, importing, cloning, loading, and writing of nodes.
➤ XmlNode — Corresponds to a node within the DOM tree. This is the base class for the other node
type classes. A robust set of methods and properties is provided to create, delete, and replace nodes.
The contents of a node can similarly be traversed in a variety of ways:
FirstChild, LastChild,
NextSibling, ParentNode, and PreviousSibling.
➤ XmlElement — Corresponds to an element within the DOM tree. The functionality exposed by this
class contains a variety of methods used to manipulate an element’s attributes.
➤ XmlAttribute — Corresponds to an attribute of an element (XmlElement) within the DOM tree.

An attribute contains data and lists of subordinate data, so it is a less complicated object than
an
XmlNode or an XmlElement. An XmlAttribute can retrieve its owner document (property,
OwnerDocument), retrieve its owner element (property, OwnerElement), retrieve its parent node
(property,
ParentNode), and retrieve its name (property, Name). The value of an XmlAttribute is
available via a read-write property named
Value. Given the diverse number of methods and properties
exposed by
XmlDocument, XmlNode, XmlElement, and XmlAttribute (and there are many more
than those listed here), it’s clear that any XML 1.0 or 1.1-compliant document can be generated and
manipulated using these classes. In comparison to their XML stream counterparts, these classes offer
more flexible movement within the XML document and through any editing of XML documents.
A similar comparison could be made between DOM and data serialized and deserialized using XML. Using
serialization, the type of node (for example, attribute or element) and the node name are specified at compile
time. There is no on-the-fly modification of the XML generated by the serialization process.
XML Stream-Style Parsers

359
Simpo PDF Merge and Split Unregistered Version -
360

CHAPTER 9 usiNG xml witH Visual BasiC
DOM Traversing XML
The first DOM example loads an XML document into an XmlDocument object using a string that contains
the actual XML document. The example over the next few pages simply traverses each XML element
(XmlNode) in the document (XmlDocument) and displays the data to the console. The data associated with
this example is contained in a variable, rawData, which is initialized as follows:
Dim rawData =
<multiFilmOrders>

<FilmOrder>
<name>Grease</name>
<filmId>101</filmId>
<quantity>10</quantity>
</FilmOrder>
<FilmOrder>
<name>Lawrence of Arabia</name>
<filmId>102</filmId>
<quantity>10</quantity>
</FilmOrder>
</multiFilmOrders>
Code snippet from DomReading
The XML document in rawData is a portion of the XML hierarchy associated with a movie order. Notice
the lack of quotation marks around the XML: This is an XML literal. XML literals allow you to insert a
block of XML directly into your VB source code. They can be written over a number of lines, and can be
used wherever you might normally load an XML file.
The basic idea in processing this data is to traverse each
<FilmOrder> element in order to display the data it
contains. Each node corresponding to a <FilmOrder> element can be retrieved from your XmlDocument using
the GetElementsByTagName method (specifying a tag name of FilmOrder). The GetElementsByTagName
method returns a list of XmlNode objects in the form of a collection of type XmlNodeList. Using the
For Each statement to construct this list, the XmlNodeList (movieOrderNodes) can be traversed as
individual XmlNode elements (movieOrderNode). The code for handling this is as follows:
Dim xmlDoc As New XmlDocument
Dim movieOrderNodes As XmlNodeList
Dim movieOrderNode As XmlNode
xmlDoc.LoadXml(rawData.ToString())
' Traverse each <FilmOrder>
movieOrderNodes = xmlDoc.GetElementsByTagName("FilmOrder")
For Each movieOrderNode In movieOrderNodes

'**********************************************************
' Process <name>, <filmId> and <quantity> here
'**********************************************************
Next
Code snippet from DomReading
Each XmlNode can then have its contents displayed by traversing the children of this node using the
ChildNodes method. This method returns an XmlNodeList (baseDataNodes) that can be traversed one
XmlNode list element at a time:
Dim baseDataNodes As XmlNodeList
Dim bFirstInRow As Boolean
baseDataNodes = movieOrderNode.ChildNodes
bFirstInRow = True
For Each baseDataNode As XmlNode In baseDataNodes
If (bFirstInRow) Then
bFirstInRow = False
Else
Console.Write(", ")
Simpo PDF Merge and Split Unregistered Version -
End If
Console.Write(baseDataNode.Name & ": " & baseDataNode.InnerText)
Next
Console.WriteLine()
Code snippet from DomReading
The bulk of the preceding code retrieves the name of the node using the Name property and the
InnerText property of the node. The InnerText property of each XmlNode retrieved contains the data
associated with the XML elements (nodes) <name>, <filmId>, and <quantity>. The example displays the
contents of the XML elements using Console.Write. The XML document is displayed to the console as
follows:
name: Grease, quantity: 10
name: Lawrence of Arabia, quantity: 10

Other, more practical, methods for using this data could have been implemented, including the following:
The contents could have been directed to an ASP.NET ➤ Response object, and the data retrieved could
have been used to create an HTML table (
<table> table, <tr> row, and <td> data) that would be
written to the
Response object.
The data traversed could have been directed to a
➤ ListBox or ComboBox Windows Forms control. This
would enable the data returned to be selected as part of a GUI application.
The data could have been edited as part of your application’s business rules. For example, you could

have used the traversal to verify that the <filmId> matched the <name>. Something like this could be
done if you wanted to validate the data entered into the XML document in any manner.
Writing XML with the DOM
You can also use the DOM to create or edit XML documents. Creating new XML items is a two-step
process, however. First, you use the containing document to create the new element, attribute, or comment
(or other node type), and then you add that at the appropriate location in the document.
Just as there are a number of methods in the DOM for reading the XML, there are also methods for
creating new nodes. The
XmlDocument class has the basic CreateNode method, as well as specific methods
for creating the different node types, such as CreateElement, CreateAttribute, CreateComment, and
others. Once the node is created, you add it in place using the AppendChild method of XmlNode (or one of
the children of XmlNode).
Create a new project that will be used to demonstrate writing XML with the DOM. Most of the work in
this sample will be done in two functions, so the
Main method can remain simple:
Sub Main()

Dim data As String
Dim fileName As String = "filmorama.xml"

data = GenerateXml(fileName)

Console.WriteLine(data)
Console.WriteLine("Press ENTER to continue")
Console.ReadLine()

End Sub
Code snippet from DomWriting
The GenerateXml function creates the initial XmlDocument, and calls the CreateFilmOrder function
multiple times to add a number of items to the structure. This creates a hierarchical XML document
that can then be used elsewhere in your application. Typically, you would use the Save method to write
XML Stream-Style Parsers

361
Simpo PDF Merge and Split Unregistered Version -
362

CHAPTER 9 usiNG xml witH Visual BasiC
the XML to a stream or document, but in this case it just retrieves the OuterXml (that is, the full XML
document) to display:
Private Function GenerateXml(ByVal fileName As String) As String
Dim result As String
Dim doc As New XmlDocument
Dim elem As XmlElement

'create root node
Dim root As XmlElement = doc.CreateElement("FilmOrderList")
doc.AppendChild(root)
'this data would likely come from elsewhere
For i As Integer = 1 To 5

elem = CreateFilmOrder(doc, i)
root.AppendChild(elem)
Next
result = doc.OuterXml
Return result
End Function
Code snippet from DomWriting
The most common error made when writing an XML document using the DOM is to create the elements
but forget to append them into the document. This step is done here with the AppendChild method, but
other methods can be used, in particular InsertBefore, InsertAfter, PrependChild, and RemoveChild.
Creating the individual
FilmOrder nodes uses a similar CreateElement/AppendChild strategy. In addition,
attributes are created using the Append method of the Attributes collection for each XmlElement:
Private Function CreateFilmOrder(ByVal parent As XmlDocument,
ByVal count As Integer) As XmlElement
Dim result As XmlElement
Dim id As XmlAttribute
Dim title As XmlElement
Dim quantity As XmlElement

result = parent.CreateElement("FilmOrder")
id = parent.CreateAttribute("id")
id.Value = 100 + count

title = parent.CreateElement("title")
title.InnerText = "Some title here"

quantity = parent.CreateElement("quantity")
quantity.InnerText = "10"


result.Attributes.Append(id)
result.AppendChild(title)
result.AppendChild(quantity)
Return result
End Function
Code snippet from DomWriting
This generates the following XML (although it will all be on one line in the output):
<FilmOrderList>
<FilmOrder id="101">
<title>Some title here</title>
<quantity> 10 </quantity>
</FilmOrder>
Simpo PDF Merge and Split Unregistered Version -
<FilmOrder id="102">
<title>Some title here</title>
<quantity> 10 </quantity>
</FilmOrder>
<FilmOrder id="103">
<title>Some title here</title>
<quantity> 10 </quantity>
</FilmOrder>
<FilmOrder id="104">
<title>Some title here</title>
<quantity>10</quantity>
</FilmOrder>
<FilmOrder id="105">
<title>
Some title here
</title>
<quantity>10</quantity>

</FilmOrder>
</FilmOrderList>
Once you get the hang of creating XML with the DOM (and forget to add the new nodes a few dozen
times), it is quite a handy method for writing XML. If the XML you need to create can all be created at
once, it is probably better to use the XmlWriter class instead. Writing XML with the DOM is best left for
those situations when you need to either edit an existing XML document or move backwards through the
document as you are writing. In addition, because the DOM is an international standard, it means that code
using the DOM is portable to other languages that also provide a DOM.
In addition to the
XmlWriter, the XElement shown later in this chapter provides yet another method for
reading and writing XML.
XSL TRANSFORMATIONS
XSLT is used to transform XML documents into another format altogether. One popular use of XSLT is
to transform XML into HTML so that XML documents can be presented visually. The idea is to use an
alternate language (XSLT) to transform the XML, rather than rewrite the source code, SQL commands, or
some other mechanism used to generate XML.
Conceptually, XSLT is straightforward. A file (a .xsl file) describes the changes (transformations) that will
be applied to a particular XML file. Once this is completed, an XSLT processor is provided with the source
XML file and the XSLT file, and performs the transformation. The
System.Xml.Xsl.XslTransform class
is such an XSLT processor. Another processor you will find (introduced in the .NET Framework 2.0) is the
XsltCommand object found at SystemXml.Query.XsltCommand. This section looks at using both of these
processors.
You can also find some features in Visual Studio that deal with XSLT. The IDE supports items such as XSLT
data breakpoints and XSLT debugging. Additionally, XSLT stylesheets can be compiled into assemblies even
more easily with the command-line stylesheet compiler,
XSLTC.exe.
The XSLT file is itself an XML document. Dozens of XSLT commands can be used in writing an XSLT file.
The first example explores the following XSLT elements (commands):
➤ stylesheet — This element indicates the start of the style sheet (XSL) in the XSLT file.

➤ template — This element denotes a reusable template for producing specific output. This output
is generated using a specific node type within the source document under a specific context. For
example, the text
<xsl: template match=“/”> selects all root nodes (“/”) for the specific
transform template. The template is applied whenever the match occurs in the source document.
XSL Transformations

363
Simpo PDF Merge and Split Unregistered Version -
364

CHAPTER 9 usiNG xml witH Visual BasiC
➤ for-each — This element applies the same template to each node in the specified set. Recall the
example class (
FilmOrderList) that could be serialized. This class contained an array of movie
orders. Given the XML document generated when a
FilmOrderList is serialized, each movie order
serialized could be processed using
<xsl:for-each select = "FilmOrderList/multiFilmOrders/FilmOrder">.
➤ value-of — This element retrieves the value of the specified node and inserts it into the document
in text form. For example,
<xsl:value-of select=“name” /> would take the value of the XML
element
<name> and insert it into the transformed document.
You can use XSLT to convert an XML document to generate a report that is viewed by the manager of the
movie supplier. This report is in HTML form so that it can be viewed via the Web. The XSLT elements
you previously reviewed (stylesheet, template, and for-each) are the only XSLT elements required to
transform the XML document (in which data is stored) into an HTML file (data that can be displayed). An
XSLT file DisplayOrders.xslt contains the following text, which is used to transform a serialized version,
FilmOrderList found in Filmorama.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet xmlns:xsl=" version="1.0">
<xsl:template match="/">
<html>
<head><title>What people are ordering</title>
</head>
<body>
<table border="1">
<tr>
<th>
Film Name
</th>
<th>
Film ID
</th>
<th>
Quantity
</th>
</tr>
<xsl:for-each select=
"//FilmOrder">
<tr>
<td>
<xsl:value-of select="Title" />
</td>
<td>
<xsl:value-of select="@id" />
</td>
<td>
<xsl:value-of select="Quantity" />

</td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
Code snippet from Transformation
Simpo PDF Merge and Split Unregistered Version -
In the preceding XSLT fi le, the XSLT elements are marked in bold. These elements perform operations on
the source XML fi le containing a serialized FilmOrderList object, and generate the appropriate HTML
fi le. Your generated fi le contains a table (marked by the table tag, < table > ) that contains a set of rows (each
row marked by a table row tag, < tr > ). The columns of the table are contained in table data tags, < td > . Each
row containing data (an individual movie order from the serialized object, FilmOrderList ) is generated
using the XSLT element, for - each , to traverse each < FilmOrder > element within the source XML
document. In this case, a shorthand for the location of the FilmOrder element was used: //FilmOrder
returns all FilmOrder elements, regardless of their depth in the XML fi le. Alternately, you could have
specifi ed the full path using FilmOrderList / FilmOrders / FilmOrder here.
The individual columns of data are generated using the
value - of XSLT element, in order to query the
elements contained within each < FilmOrder > element ( < Title > , < id > , and < Quantity > ) .
The code in
Sub Main() to create a displayable XML fi le using the XslCompiledTransform object is as
follows:
Dim xslt As New XslCompiledTransform
Dim outputFile As String = " \ \output.html"

xslt.Load(" \ \displayorders.xslt")
xslt.Transform(" \ \filmorama.xml", outputFile)


Process.Start(outputFile)
Code snippet from Transformation
This consists of only fi ve lines of code, with the
bulk of the coding taking place in the XSLT fi le.
The previous code snippet created an instance of
a System.Xml.Xsl.XslCompiledTransform
object named xslt . The Load method of this
class is used to load the XSLT fi le you previously
reviewed, DisplayOrders.xslt . The Transform
method takes a source XML fi le as the fi rst
parameter, which in this case was a fi le containing
a serialized FilmOrderList object. The second
parameter is the destination fi le created by the
transform ( Output.html ). The Start method
of the Process class is used to display the
HTML fi le in the system default browser. This
method launches a process that is best suited
for displaying the fi le provided. Basically, the
extension of the fi le dictates which application will
be used to display the fi le. On a typical Windows
machine, the program used to display this fi le is
Internet Explorer, as shown in Figure 9 - 2.
Don ’ t confuse displaying this HTML fi le with ASP.NET. Displaying an HTML fi le in
this manner takes place on a single machine without the involvement of a Web server.
FIGURE 9  2
As demonstrated, the backbone of the System.Xml.Xsl namespace is the XslCompiledTransform class.
This class uses XSLT fi les to transform XML documents. XslCompiledTransform exposes the following
methods and properties:
➤ XmlResolver — This get/set property is used to specify a class (abstract base class, XmlResolver )

that is used to handle external references (import and include elements within the style sheet). These
XSL Transformations

365
Simpo PDF Merge and Split Unregistered Version -
366

CHAPTER 9 usiNG xml witH Visual BasiC
external references are encountered when a document is transformed (the method, Transform, is
executed). The
System.Xml namespace contains a class, XmlUrlResolver, which is derived from
XmlResolver. The XmlUrlResolver class resolves the external resource based on a URI.
➤ Load — This overloaded method loads an XSLT style sheet to be used in transforming XML
documents. It is permissible to specify the XSLT style sheet as a parameter of type
XPathNavigator,
filename of an XSLT file (specified as parameter type
String), XmlReader, or IXPathNavigable.
For each type of XSLT supported, an overloaded member is provided that enables an
XmlResolver to
also be specified. For example, it is possible to call
Load(String, XsltSettings, XmlResolver),
where
String corresponds to a filename, XsltSettings is an object that contains settings to affect the
transformation, and
XmlResolver is an object that handles references in the style sheet of type

xsl:import and xsl:include. It would also be permissible to pass in a value of Nothing for the
third parameter of the
Load method (so that no XmlResolver would be specified).
➤ Transform — This overloaded method transforms a specified XML document using the previously

specified XSLT style sheet. The location where the transformed XML is to be output is specified as a
parameter to this method. The first parameter of each overloaded method is the XML document to
be transformed. The most straightforward variant of the
Transform method is Transform(String,
String)
. In this case, a file containing an XML document is specified as the first parameter, and a
filename that receives the transformed XML document is specified as the second. This is exactly how
the first XSLT example utilized the
Transform method:
myXslTransform.Transform(" \FilmOrders.xml", destFileName)
The first parameter to the Transform method can also be specified as IXPathNavigable or XmlReader.
The XML output can be sent to an object of type Stream, TextWriter, or XmlWriter. In addition, a
parameter containing an object of type XsltArgumentList can be specified. An XsltArgumentList object
contains a list of arguments that are used as input to the transform. These may be used within the XSLT file
to affect the output.
XSLT Transforming between XML Standards
The first example used four XSLT elements to transform an XML file into an HTML file. Such an example
has merit, but it doesn’t demonstrate an important use of XSLT: transforming XML from one standard into
another standard. This may involve renaming elements/attributes, excluding elements/attributes, changing
data types, altering the node hierarchy, and representing elements as attributes, and vice versa.
Returning to the example, a case of differing XML standards could easily affect your software that automates
movie orders coming into a supplier. Imagine that the software, including its XML representation of a movie
order, is so successful that you sell 100,000 copies. However, just as you are celebrating, a consortium of
the largest movie supplier chains announces that they are no longer accepting faxed orders and that they are
introducing their own standard for the exchange of movie orders between movie sellers and buyers.
Rather than panic, you simply ship an upgrade that includes an XSLT file. This upgrade (a bit of extra code
plus the XSLT file) transforms your XML representation of a movie order into the XML representation
dictated by the consortium of movie suppliers. Using an XSLT file enables you to ship the upgrade
immediately. If the consortium of movie suppliers revises their XML representation, then you are not
obliged to change your source code. Instead, you can simply ship the upgraded XSLT file that ensures each

movie order document is compliant.
The specific source code that executes the transform is as follows:
Dim xslt As New XslCompiledTransform
Dim outputFile As String = " \ \output.html"

xslt.Load(" \ \displayorders.xslt")
xslt.Transform(" \ \filmorama.xml", outputFile)
Code snippet from Transformation
Simpo PDF Merge and Split Unregistered Version -
Those three lines of code accomplish the following:
Create an ➤ XslCompiledTransform object
Use the
➤ Load method to load an XSLT file (ConvertLegacyToNewStandard.xslt)
Use the
➤ Transform method to transform a source XML file (MovieOrdersOriginal.xml) into a
destination XML file (
MovieOrdersModified.xml)
Recall that the input XML document (MovieOrdersOriginal.xml) does not match the format required by
your consortium of movie supplier chains. The content of this source XML file is as follows:
<?xml version="1.0" encoding="utf-8" ?>
<FilmOrderList>
<multiFilmOrders>
<FilmOrder>
<name>Grease</name>
<filmId>101</filmId>
<quantity>10</quantity>
</FilmOrder>

</multiFilmOrders>
</FilmOrderList>

Code snippet from Transformation
The format exhibited in the preceding XML document does not match the format of the consortium of
movie supplier chains. To be accepted by the collective of suppliers, you must transform the document as
follows:
Remove element ➤ <FilmOrderList>.
Remove element
➤ <multiFilmOrders>.
Rename element
➤ <FilmOrder> to <DvdOrder>.
Remove element
➤ <name> (the film’s name is not to be contained in the document).
Rename element
➤ <quantity> to HowMuch and make HowMuch an attribute of <DvdOrder>.
Rename element
➤ <filmId> to FilmOrderNumber and make FilmOrderNumber an attribute of
<DvdOrder>.
Display attribute
➤ HowMuch before attribute FilmOrderNumber.
Many of the steps performed by the transform could have been achieved using an alternative technology.
For example, you could have used Source Code Style attributes with your serialization to generate the
correct XML attribute and XML element name. Had you known in advance that a consortium of suppliers
was going to develop a standard, you could have written your classes to be serialized based on the standard.
The point is that you did not know, and now one standard (your legacy standard) has to be converted into
a newly adopted standard of the movie suppliers’ consortium. The worst thing you could do would be to
change your working code and then force all users working with the application to upgrade. It is vastly
simpler to add an extra transformation step to address the new standard.
The XSLT file that facilitates the transform is named
ConvertLegacyToNewStandard.xslt. A portion of
this file is implemented as follows:
<?xml version="1.0" encoding="utf-8"?>

<xsl:stylesheet version="1.0" xmlns:xsl=" /> <xsl:template match="FilmOrder">
<! rename <FilmOrder> to <DvdOrder>
>
<xsl:element name="DvdOrder">
<! Make element Quantity attribute HowMuch
Notice attribute HowMuch comes before attribute FilmOrderNumber >
<xsl:attribute name="HowMuch">
XSL Transformations

367
Simpo PDF Merge and Split Unregistered Version -
368

CHAPTER 9 usiNG xml witH Visual BasiC
<xsl:value-of select="Quantity"></xsl:value-of>
</xsl:attribute>
<! Make element id attribute FilmOrderNumber >
<xsl:attribute name="FilmOrderNumber">
<xsl:value-of select="@id"></xsl:value-of>
</xsl:attribute>
</xsl:element>
<! end of DvdOrder element >
</xsl:template>
</xsl:stylesheet>
Code snippet from Transformation
In the previous snippet of XSLT, the following XSLT elements are used to facilitate the transformation:
➤ <xsl:template match=“FilmOrder”> — All operations in this template XSLT element take place
on the original document’s
FilmOrder node.
➤ <xsl:element name=“DvdOrder”> — The element corresponding to the source document’s

FilmOrder element will be called DvdOrder in the destination document.
➤ <xsl:attribute name=“HowMuch”> — An attribute named HowMuch will be contained in the
previously specified element,
<DvdOrder>. This attribute XSLT element for HowMuch comes before the
attribute XSLT element for
FilmOrderNumber. This order was specified as part of your transform to
adhere to the new standard.
➤ <xsl:value-of select=‘Quantity’> — Retrieve the value of the source document’s <Quantity>
element and place it in the destination document. This instance of XSLT element
value-of provides
the value associated with the attribute
HowMuch.
Two new XSLT terms have crept into your vocabulary: element and attribute. Both of these XSLT
elements live up to their names. Using the element node in an XSLT places an element in the destination
XML document, while an attribute node places an attribute in the destination XML document. The
XSLT transform found in ConvertLegacyToNewStandard.xslt is too long to review here. When reading
this file in its entirety, remember that this XSLT file contains inline documentation to specify precisely what
aspect of the transformation is being performed at which location in the XSLT document. For example, the
following XML code comments indicate what the XSLT element attribute is about to do:
<! Make element 'Quantity' attribute HowMuch
Notice attribute HowMuch comes before attribute FilmOrderNumber >
<xsl:attribute name="HowMuch">
<xsl:value-of select='Quantity'></xsl:value-of>
</xsl:attribute>
Code snippet from Transformation
The preceding example spans several pages but contains just three lines of code. This demonstrates that
there is more to XML than learning how to use it in Visual Basic and the .NET Framework. Among other
things, you also need a good understanding of XSLT, XPath, and XQuery. For more details on these
standards, see Professional XML from Wrox.
Other Classes and Interfaces in System.Xml.Xsl

We just took a good look at XSLT and the System.Xml.Xsl namespace, but there is a lot more to it than
that. Other classes and interfaces exposed by the System.Xml.Xsl namespace include the following:
➤ IXsltContextFunction — This interface accesses at runtime a given function defined in the XSLT
style sheet.
➤ IXsltContextVariable — This interface accesses at runtime a given variable defined in the XSLT
style sheet.
Simpo PDF Merge and Split Unregistered Version -
➤ XsltArgumentList — This class contains a list of arguments. These arguments are XSLT parameters
or XSLT extension objects. The
XsltArgumentList object is used in conjunction with the
Transform method of XslTransform. Arguments enable you to use a single XSLT transformation for
multiple uses, changing the parameters of the transformation as needed.
➤ XsltContext — This class contains the state of the XSLT processor. This context information
enables XPath expressions to have their various components resolved (functions, parameters, and
namespaces).
➤ XsltException, XsltCompileException — These classes contain the information pertaining to an
exception raised while transforming data.
XsltCompileException is derived from XsltException
and is thrown by the
Load method.
XML IN ASP.NET
Most Microsoft-focused Web developers have usually concentrated on either Microsoft SQL Server or
Microsoft Access for their data storage needs. Today, however, a large amount of data is stored in XML
format, so considerable inroads have been made in improving Microsoft’s core Web technology to work
easily with this format.
The XmlDataSource Server Control
ASP.NET contains a series of data source controls designed to bridge the gap between your data stores
(such as XML) and the data-bound controls at your disposal. These new data controls not only enable you
to retrieve data from various data stores, they also enable you to easily manipulate the data (using paging,
sorting, editing, and filtering) before the data is bound to an ASP.NET server control.

With XML being as important as it is, a specific data source control is available in ASP.NET just for
retrieving and working with XML data:
XmlDataSource. This control enables you to connect to your XML
data and use this data with any of the ASP.NET data-bound controls. Just like the SqlDataSource and the
ObjectDataSource controls, the XmlDataSource control enables you to not only retrieve data, but also
insert, delete, and update data items. With increasing numbers of users turning to XML data formats, such
as Web services, RSS feeds, and more, this control is a valuable resource for your Web applications.
To show the
XmlDataSource control in action, first create a simple XML file and include this file in your
application. The following code reflects a simple XML file of Russian painters:
<?xml version="1.0" encoding="utf-8" ?>
<Artists>
<Painter name="Vasily Kandinsky">
<Painting>
<Title>Composition No. 218</Title>
<Year>1919</Year>
</Painting>
</Painter>
<Painter name="Pavel Filonov">
<Painting>
<Title>Formula of Spring</Title>
<Year>1929</Year>
</Painting>
</Painter>
<Painter name="Pyotr Konchalovsky">
<Painting>
<Title>Sorrento Garden</Title>
<Year>1924</Year>
</Painting>
</Painter>

</Artists>
Code snippet from XmlWeb
XML in ASP.NET

369
Simpo PDF Merge and Split Unregistered Version -
370

CHAPTER 9 usiNG xml witH Visual BasiC
Now that the Painters.xml file is in place, the next step is to use an ASP.NET DataList control and
connect this DataList control to an <asp:XmlDataSource> control, as shown here:
<%@ Page Language="vb" AutoEventWireup="false"
CodeBehind="Default.aspx.vb" Inherits="XmlWeb._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
" /><html xmlns=" /><head runat="server">
<title>Using XmlDataSource</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="PainterList" runat="server"
DataSourceID="PainterData">
<ItemTemplate>
<p>
<b>
<%# XPath("@name") %></b><br />
<i>
<%# XPath("Painting/Title") %></i><br />
<%# XPath("Painting/Year") %></p>

</ItemTemplate>
</asp:DataList>
<asp:XmlDataSource ID="PainterData" runat="server"
DataFile="~/Painters.xml" XPath="Artists/Painter" />
</div>
</form>
</body>
</html>
Code snippet from XmlWeb
This is a simple example, but it shows you the power and ease of using the XmlDataSource control. Pay attention
to two attributes in this example. The first is the DataFile attribute. This attribute points to the location of the
XML file. Because the file resides in the root directory of the Web application, it is simply ~/Painters.xml. The
next attribute included in the XmlDataSource control is the XPath attribute. The XmlDataSource control uses
XPath for the filtering of XML data. In this case, the XmlDataSource control
is taking everything within the <Painter> set of elements. The value Artists/
Painter means that the XmlDataSource control navigates to the <Artists>
element and then to the <Painter> element within the specified XML file.
The
DataList control next must specify the DataSourceID as the
XmlDataSource control. In the <ItemTemplate> section of the DataList
control, you can retrieve specific values from the XML file by using XPath
commands. The XPath commands filter the data from the XML file. The first
value retrieved is an element attribute (name) contained in the <Painter>
element. When you retrieve an attribute of an element, you preface the name
of the attribute with an @ symbol. In this case, you simply specify @name to
get the painter’s name. The next two XPath commands go deeper into the
XML file, getting the specific painting and the year of the painting. Remember
to separate nodes with a /. When run in the browser, this code produces the
results shown in Figure 9-3.
Besides working from static XML files such as the

Painters.xml file, the XmlDataSource file can work
from dynamic, URL-accessible XML files. One popular XML format pervasive on the Internet today is
blogs, or weblogs. Blogs can be viewed either in the browser (see Figure 9-4), through an RSS aggregator, or
just as pure XML.
FIGURE 93
Simpo PDF Merge and Split Unregistered Version -
FIGURE 94
Now that you know the location of the XML from the blog, you can use this XML with the XmlDataSource
control and display some of the results in a DataList control. The code for this example is shown here:
<%@ Page Language="vb" AutoEventWireup="false"
CodeBehind="Default.aspx.vb" Inherits="ViewingRss._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
" /><html xmlns=" /><head runat="server">
<title>Viewing RSS</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:DataList ID="RssList" runat="server"
DataSourceID="RssData">
<HeaderTemplate>
<table border="1" cellpadding="3">
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<b>
<%# XPath("title") %></b><br />
<i>

<%# "published on " + XPath("pubDate") %></i><br />
<%# XPath("description").ToString().Substring(0,100) %>
</td>
</tr>
</ItemTemplate>
<AlternatingItemTemplate>
<tr style="background-color: #e0e0e0;">
<td>
<b>
<%# XPath("title") %></b><br />
<i>
<%# "published on " + XPath("pubDate") %></i><br />
<%# XPath("description").ToString().Substring(0,100) %>
XML in ASP.NET

371
Simpo PDF Merge and Split Unregistered Version -
372

CHAPTER 9 usiNG xml witH Visual BasiC
</td>
</tr>
</AlternatingItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:DataList>
<asp:XmlDataSource ID="RssData" runat="server"
DataFile=" /> XPath="rss/channel/item" />
</div>

</form>
</body>
</html>
Code snippet from ViewingRSS
This example shows that the DataFile points to a URL where the XML is retrieved. The XPath property
filters out all the <item> elements from the RSS feed. The DataList control creates an HTML table and
pulls out specific data elements from the RSS feed, such as the <title>, <pubDate>, and <description>
elements. To make things a little more visible, only the first 100 characters of each post are displayed.
Running this page in the browser results in something similar to what is shown in Figure 9-5.
FIGURE 95
Simpo PDF Merge and Split Unregistered Version -
This approach also works with XML Web Services, even those for which you can pass in parameters using
HTTP-GET. You just set up the DataFile value in the following manner:
DataFile=" />The XmlDataSource Control’s Namespace Problem
One big issue with using the XmlDataSource control is that when using the XPath capabilities of the control,
it is unable to understand namespace-qualified XML. The XmlDataSource control chokes on any XML data
that contains namespaces, so it is important to yank out any prefixes and namespaces contained in the XML.
To make this a bit easier, the
XmlDataSource control includes the TransformFile attribute. This attribute
takes your XSLT transform file, which can be applied to the XML pulled from the XmlDataSource control.
That means you can use an XSLT file, which will transform your XML in such a way that the prefixes and
namespaces are completely removed from the overall XML document. An example of this XSLT document
is illustrated here:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" /> <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="*">
<! Remove any prefixes >
<xsl:element name="{local-name()}">
<! Work through attributes >

<xsl:for-each select="@*">
<! Remove any attribute prefixes >
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:for-each>
<xsl:apply-templates/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>
Now, with this XSLT document in place within your application, you can use the XmlDataSource control to
pull XML data and strip that data of any prefixes and namespaces:
<asp:XmlDataSource ID="XmlDataSource1" runat="server"
DataFile="NamespaceFilled.xml" TransformFile="~/RemoveNamespace.xsl"
XPath="ItemLookupResponse/Items/Item"></asp:XmlDataSource>
The Xml Server Control
Since the very beginning of ASP.NET, there has always been a server control called the Xml server control.
This control performs the simple operation of XSLT transformation upon an XML document. The control
is easy to use: All you do is point to the XML file you wish to transform using the DocumentSource
attribute, and the XSLT transform file using the TransformSource attribute.
To see this in action, use the
Painters.xml file shown earlier. Create your XSLT transform file, as shown in
the following example:
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl=" /> <xsl:template match="/">
<html>
<body>
<h3>List of Painters &amp; Paintings</h3>
<table border="1">

<tr bgcolor="LightGrey">
<th>Name</th>
XML in ASP.NET

373
Simpo PDF Merge and Split Unregistered Version -
374

CHAPTER 9 usiNG xml witH Visual BasiC
<th>Painting</th>
<th>Year</th>
</tr>
<xsl:apply-templates select="//Painter"/>
</table>
</body>
</html>
</xsl:template>
<xsl:template match="Painter">
<tr>
<td>
<xsl:value-of select="@name"/>
</td>
<td>
<xsl:value-of select="Painting/Title"/>
</td>
<td>
<xsl:value-of select="Painting/Year"/>
</td>
</tr>
</xsl:template>

</xsl:stylesheet>
Code snippet from XmlControl
With the XML document and the XSLT document in place, the final step is to combine the two using the
Xml server control provided by ASP.NET in default.aspx:
<%@ Page Language="vb" AutoEventWireup="false"
CodeBehind="Default.aspx.vb" Inherits="XmlControl._Default" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
" />
<html xmlns=" >
<head runat="server">
<title>Using the Xml Control</title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Xml ID="PainterView" runat="server"
DocumentSource="~/Painters.xml"
TransformSource="~/painters.xslt" />
</div>
</form>
</body>
</html>
Code snippet from XmlControl
The result is shown in Figure 9-6.
FIGURE 96
Simpo PDF Merge and Split Unregistered Version -
LINQ TO XML
With the introduction of LINQ to the .NET Framework, the focus was on easy access to the data that you want
to work with in your applications. One of the main data stores in the application space is XML, so it was really

a no - brainer to create the LINQ to XML implementation. With the inclusion of System.Xml.Linq , you now
have a series of capabilities that make the process of working with XML in your code much easier to achieve.
LINQ HELPER XML OBJECTS
Even if the LINQ querying capability were not around, the new objects available to work with the XML
are so good that they can even stand on their own outside LINQ. Within the new System.Xml.Linq
namespace, you will fi nd a series of new LINQ to XML helper objects that make working with an XML
document in memory that much easier. The following sections describe the new objects that are available
within this new namespace.
Many of the examples in this chapter use a fi le called Hamlet.xml , which you can fi nd
included in the fi le . At this
link you ’ ll fi nd all of Shakespeare ’ s plays as XML fi les.
X D o c u m e n t
The XDocument class is a replacement of the XmlDocument object from the pre - LINQ world. While it
does not comply with any international standards, the XDocument object is easier to work with when
dealing with XML documents. It works with the other new objects in this space, such as the XNamespace ,
XComment , XElement , and XAttribute objects.
One of the more important members of the
XDocument object is the Load method:
Dim xdoc As XDocument = XDocument.Load("C:\Hamlet.xml")
The preceding example loads the Hamlet.xml contents as an in - memory XDocument object. You can also
pass a TextReader or XmlReader object into the Load method. From here, you can programmatically work
with the XML:
Dim xdoc As XDocument = XDocument.Load("C:\Hamlet.xml")
Console.WriteLine(xdoc.Root.Name.ToString())
Console.WriteLine(xdoc.Root.HasAttributes.ToString())
Code snippet from LinqRead
This produces the following results:
PLAY
False
Another important member to be aware of is the Save method, which, like the Load method, enables you to

save to a physical disk location or to a TextWriter or XmlWriter object. Note that you need to be running
the application (or Visual Studio) as an administrator for this to work, as it writes to the root directory:
Dim xdoc As XDocument = XDocument.Load("C:\Hamlet.xml")
xdoc.Save("C:\CopyOfHamlet.xml")
X E l e m e n t
Another common object that you will work with is the XElement object. With this object, you can easily
create even single - element objects that are XML documents themselves, and even fragments of XML. For
instance, here is an example of writing an XML element with a corresponding value:
Dim xe As XElement = New XElement("Company", "Wrox")
Console.WriteLine(xe.ToString())
LINQ Helper XML Objects

375
Simpo PDF Merge and Split Unregistered Version -
376

CHAPTER 9 usiNG xml witH Visual BasiC
When creating a new XElement object, you can define the name of the element as well as the value used
in the element. In this case, the name of the element will be <Company>, while the value of the <Company>
element will be Wrox. Running this in a console application, you will get the following result:
<Company>Wrox</Company>
You can also create a more complete XML document using multiple XElement objects, as shown here:
Imports System.Xml.Linq

Module Main

Sub Main()

Dim root As New XElement("Company",
New XAttribute("Type", "Publisher"),

New XElement("CompanyName", "Wrox"),
New XElement("CompanyAddress",
New XElement("Steet", "111 River Street"),
New XElement("City", "Hoboken"),
New XElement("State", "NJ"),
New XElement("Country", "USA"),
New XElement("Zip", "07030-5774")))
Console.WriteLine(root.ToString())
Console.WriteLine("Press ENTER to exit")
Console.ReadLine()
End Sub

End Module
Code snippet from XElementWriting
Running this application yields the results shown in Figure 9-7.
FIGURE 97
XNamespace
The XNamespace is an object that represents an XML namespace, and it is easily applied to elements within your
document. For example, you can take the previous example and easily apply a namespace to the root element:
Imports System.Xml.Linq

Module Main

Sub Main()
Dim ns as Xnamespace = " /> Dim root As New Xelement(ns + "Company",
Simpo PDF Merge and Split Unregistered Version -
New XElement("CompanyName", "Wrox"),
New XElement("CompanyAddress",
New XElement("Street", "111 River Street"),
New XElement("City", "Hoboken"),

New XElement("State", "NJ"),
New XElement("Country", "USA"),
New XElement("Zip", "07030-5774")))
Console.WriteLine(root.ToString())
Console.WriteLine("Press ENTER to exit")
Console.ReadLine()
End Sub

End Module
In this case, an XNamespace object is created by assigning it a value of />somenamespace
. From there, it is actually used in the root element <Company> with the instantiation of the
XElement object:
Dim root As New XElement(ns + "Company",
This will produce the results shown in Figure 9-8.
FIGURE 98
Besides dealing with the root element, you can also apply namespaces to all your elements:
Imports System.Xml.Linq

Module Main

Sub Main()
Dim ns1 As XNamespace = " /> Dim ns2 As XNamespace = " />
Dim root As New XElement(ns1 + "Company",
New XElement(ns1 + "CompanyName", "Wrox"),
New XElement(ns2 + "CompanyAddress",
New XElement(ns2 + "Street", "111 River Street"),
New XElement(ns2 + "City", "Hoboken"),
New XElement(ns2 + "State", "NJ"),
New XElement(ns2 + "Country", "USA"),
New XElement(ns2 + "Zip", "07030-5774")))

Console.WriteLine(root.ToString())
Console.WriteLine("Press ENTER to exit")
Console.ReadLine()
End Sub

End Module
Code snippet from XElementWritingNamespaces
LINQ Helper XML Objects

377
Simpo PDF Merge and Split Unregistered Version -
378

CHAPTER 9 usiNG xml witH Visual BasiC
This produces the results shown in Figure 9-9.
FIGURE 99
In this case, the subnamespace was applied to everything specified except for the <Street>, <City>,
<State>, <Country>, and <Zip> elements, because they inherit from their parent, <CompanyAddress>,
which has the namespace declaration.
XAttribute
In addition to elements, another important aspect of XML is attributes. Adding and working with attributes
is done through the use of the XAttribute object. The following example adds an attribute to the root
<Company> node:
Dim root As New Xelement("Company",
New Xattribute("Type", "Publisher"),
New XElement("CompanyName", "Wrox"),
New XElement("CompanyAddress",
New XElement("Street", "111 River Street"),
New XElement("City", "Hoboken"),
New XElement("State", "NJ"),

New XElement("Country", "USA"),
New XElement("Zip", "07030-5774")))
Here, the attribute MyAttribute with a value of MyAttributeValue is added to the root element of the
XML document, producing the results shown in Figure 9-10.
FIGURE 910
Simpo PDF Merge and Split Unregistered Version -
VISUAL BASIC AND XML LITERALS
Visual Basic takes LINQ to XML one step further, enabling you to place XML directly in your code. Using
XML literals, you can place XML directly in your code for working with the XDocument and XElement
objects. Earlier, the use of the XElement object was presented as follows:
Imports System.Xml.Linq

Module Main

Sub Main()
Dim root As New XElement("Company",
New XElement("CompanyName", "Wrox"),
New XElement("CompanyAddress",
New XElement("Street", "111 River Street"),
New XElement("City", "Hoboken"),
New XElement("State", "NJ"),
New XElement("Country", "USA"),
New XElement("Zip", "07030-5774")))
Console.WriteLine(root.ToString())
Console.WriteLine("Press ENTER to exit")
Console.ReadLine()
End Sub

End Module
Code snippet from XmlLiteral

Using XML literals, you can use the following syntax:
Module Main

Sub Main()
Dim root As XElement =
<Company>
<CompanyName>Wrox</CompanyName>
<CompanyAddress>
<Street>111 River Street</Street>
<City>Hoboken</City>
<State>NJ</State>
<Country>USA</Country>
<Zip>07030-5774</Zip>
</CompanyAddress>
</Company>
Console.WriteLine(root.ToString())
Console.WriteLine("Press ENTER to exit")
Console.ReadLine()
End Sub

End Module
Code snippet from XmlLiteral
This enables you to place the XML directly in the code (see Figure 9-11). The best part about this is the IDE
support for XML literals. Visual Studio 2010 has IntelliSense and excellent color-coding for the XML that
you place in your code file.
Visual Basic and XML Literals

379
Simpo PDF Merge and Split Unregistered Version -
380


CHAPTER 9 usiNG xml witH Visual BasiC
You can also use inline variables in the XML document. For instance, if you wanted to declare the value
of the <CompanyName> element outside the XML literal, then you could use a construct similar to the
following:
Module Module1
Sub Main()
Dim companyName As String = "Wrox"
Dim xe As XElement = _
<Company>
<CompanyName><%= companyName %></CompanyName>
<CompanyAddress>
<Street>111 River Street</Street>
<City>Hoboken</City>
<State>NJ</State>
<Country>USA</Country>
<Zip>07030-5774</Zip>
</CompanyAddress>
</Company>
Console.WriteLine(xe.ToString())
Console.ReadLine()
End Sub
End Module
In this case, the <CompanyName> element is assigned a value of Wrox from the companyName variable, using
the syntax <%= companyName %>.
USING LINQ TO QUERY XML DOCUMENTS
Now that you can get your XML documents into an XDocument object and work with the various parts of
this document, you can also use LINQ to XML to query your XML documents and work with the results.
Querying Static XML Documents
Notice that querying a static XML document using LINQ to XML takes almost no work at all. The

following example makes use of the hamlet.xml file, querying for all the players (actors) who appear in a
play. Each of these players is defined in the XML document with the <PERSONA> element:
Module Main
Sub Main()
Dim xdoc As XDocument = XDocument.Load("C:\hamlet.xml")
Dim query = From people In xdoc.Descendants("PERSONA") _
Select people.Value
FIGURE 911
Simpo PDF Merge and Split Unregistered Version -

×