Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Beginning Visual Basic 2005 Express Edition - From Novice To Professional (2006)

.pdf
Скачиваний:
387
Добавлен:
17.08.2013
Размер:
21.25 Mб
Скачать

380

C H A P T E R 1 4 F I L E S A N D S T R E A M S

The next step, and the most important from our point of view, is to grab the stream underneath the response and then attach a reader to it. This is handled with a call to GetResponseStream():

Sub Main()

Dim request As WebRequest

request = WebRequest.Create("http://www.apress.com")

Dim response As WebResponse = request.GetResponse()

Dim responseStream As Stream = response.GetResponseStream()

Dim reader As New StreamReader(responseStream)

End Sub

If you’re comfortable with nesting method calls inside method calls, you can simplify this code a lot:

Sub Main()

Dim reader As New StreamReader( _ WebRequest.Create("http://www.apress.com" _ ).GetResponse().GetResponseStream() _

)

End Sub

Now that you have a stream, you can get data from it just as if it were a file. Let’s dump the entire web page to the console:

Sub Main()

Dim reader As New StreamReader( _ WebRequest.Create("http://www.apress.com" _ ).GetResponse().GetResponseStream() _

)

Dim line As String = reader.ReadLine() Do

Console.WriteLine(line) line = reader.ReadLine()

Loop While Not line Is Nothing

Console.ReadLine()

End Sub

C H A P T E R 1 4 F I L E S A N D S T R E A M S

381

Run the program now and you’ll see HTML gibberish splattered all over your console window, just as in Figure 14-9.

Figure 14-9. After you have a stream, regardless of where it came from, you can work with it just as any other.

If on the other hand you wanted to send specific data to the server, you could do so by asking the WebRequest object for its RequestStream. For example (don’t type this in):

request.GetRequestStream()

From that point, you’re free to attach a writer in the usual way and send data to the server.

Summary

As you’ve seen here, working with streams, readers, and writers is easy. When you know how to use one type of stream (a file stream, for example) you really are well equipped to work with any other. Feel free to explore the various streams, readers, and writers in the online help and experiment with the code here to find out more.

C H A P T E R 1 5

■ ■ ■

Working with XML

In recent years eXtensible Markup Language (XML) has taken the world of computers by storm. It’s the format used to store information about word processing documents, price lists on websites, and details of blog posts on people’s web logs. In .NET XML can be used to send huge snippets of database data across the Internet. If you talk to a web service with your Visual Basic program (something we cover in the next chapter), the data exchanged between the web service and your program behind the scenes is XML. In short, there’s no escaping XML these days.

XML is simply a way of adding structure to data. If I wanted to store a list of products in a file, I could create an XML file that looks like this:

<ProductList>

<Product Reference="1234" Price="12.99"> My super dooper widget

</Product>

<Product Reference="8832" Price="59.75"> Whizz-Bang Jiggle Doobry

</Product>

</ProductList>

It looks a bit like a web page, doesn’t it, with all those angle brackets everywhere. The reason is that HyperText Markup Language (HTML), the language used to produce a web page, is itself derived from something called Standard Generalized Markup Language (SGML). SGML is the language used to define XML.

If that sounds unnecessarily complex, that’s because it is. The beauty of XML is actually its simplicity. The things inside the angle brackets are called elements (tags in HTML) and they can be anything you want them to be. The only rule is that you need to both open and close all elements. For example, in the preceding snippet I have an element called <ProductList> that starts the document, and another at the end called </ProductList>. </ProductList> closes <ProductList>. Similarly, for every <Product> element you’ll find a matching </Product> one.

Elements can also have things attached called attributes. In the preceding example, each product element has two attributes: Reference and Price. As you can see, you define an attribute simply by placing it after the element name and putting the attribute’s value

within quotation marks.

383

384 C H A P T E R 1 5 W O R K I N G W I T H X M L

In this chapter you’re going to explore the XML features of the Visual Basic 2005 Express IDE as well as the .NET Framework’s support for XML. If you’ve never come across XML before, I would strongly urge you to take a look at http://www.xml.com, the spiritual home of XML on the Internet. There you’ll find plenty of overview articles and tutorials on just what XML is and why it’s so cool.

I should also point out that even though XML is everywhere these days, and a valuable thing to learn how to work with, you could go your whole programming life and never need to deal with it. It would be kind of like driving from one end of the country to the other on dirt roads—an interesting and colorful adventure, but perhaps not the best way to get things done.

The fact is that XML can make so many data management tasks simple, it’s worth adding to your Visual Basic programming arsenal.

System.Xml

The classes that let you work with XML documents live in the System.Xml namespace. XML documents are like a tree. The document itself contains elements, and elements contain values, attributes, or other elements, and so on. The classes in System.Xml work the same way.

When you create an XML document in code, you call methods on an XMLDocument object. XMLDocument objects have a ChildNodes collection. Every item in an XML document, from elements to attributes and even directives (the funny elements that begin with <?—again see http://www.xml.org for more information), are represented in the framework as classes that subclass XmlNode. So, using the ChildNodes collection, which contains a bunch of XmlNode objects, you can get at everything inside the document.

This method of working—hitting an XML document directly—provides by far the most power and flexibility of all the ways of handling XML in the .NET Framework. However, it also requires the most work. In addition, if you’re something of an XML guru, this is definitely the way you’ll want to go. With that in mind, let’s do a short “Try It Out” to see the XMLDocument object in action, before we settle down into the simpler ways of working with XML.

Try It Out: Working with XMLDocument

Most blogs these days use an XML format known as RSS to expose their content. With RSS and an RSS reader you can simply “subscribe” to a blog and have it automatically download new content to your computer and alert you when it arrives. We’re not going to develop an RSS reader here, but RSS is a complex enough XML format that it’s fun to explore. Let’s write an application that will download an RSS feed and then show us what’s inside it, in .NET terms.

C H A P T E R 1 5 W O R K I N G W I T H X M L

385

First, start up a new Windows project in Visual Basic 2005 Express. When the form appears in the designer, drop a button and a list box onto it, so the form looks like Figure 15-1.

Figure 15-1. Drop a list box and a button onto the form of your project.

Set the Name property of the button to getXML and the Name property of the list box to xmlList. When you’re finished, double-click the button to drop into the code editor for its Click event handler.

Each time the button is clicked, you’ll grab the RSS feed for the Apress blogs (ablog.apress.com) and then populate the list box with a breakdown of the document’s contents. So, the first thing you need to do is empty the list box and grab your XML document (and of course add an Imports statement so that you can work with the WebClient) class:

Imports System.Net

Public Class Form1

Private Sub getXML_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles getXML.Click

xmlList.Items.Clear()

Dim xml As String = New WebClient().DownloadString( _ "http://blogs.apress.com/wp-rss2.php")

End Sub End Class

Don’t panic if this looks a little foreign. After clearing the list box contents, the next line uses the WebClient class to download your RSS feed into a string.

386

C H A P T E R 1 5 W O R K I N G W I T H X M L

Now that you have your RSS feed nicely downloaded into a string variable, the next task is to load the contents of that string variable into an XMLDocument object. First, add yet another Imports statement, this time to reference the System.Xml namespace:

Imports System.Net

Imports System.Xml

Public Class Form1

Private Sub getXML_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles getXML.Click

xmlList.Items.Clear()

Dim xml As String = New WebClient().DownloadString( _ "http://blogs.apress.com/wp-rss2.php")

End Sub

End Class

With that done, you can start writing code to use the XmlDocument class. XmlDocument has a handy method called LoadXml(), which is designed to load XML from a string variable into the XmlDocument object. So, all it takes to turn your downloaded RSS feed into an XML document that you can work with is just two lines of code. Add them to the Click handler:

Imports System.Net

Imports System.Xml

Public Class Form1

Private Sub getXML_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles getXML.Click

xmlList.Items.Clear()

Dim xml As String = New WebClient().DownloadString( _ "http://blogs.apress.com/wp-rss2.php")

Dim doc As New XmlDocument() doc.LoadXml(xml)

End Sub

End Class

C H A P T E R 1 5 W O R K I N G W I T H X M L

387

Now, as I mentioned earlier, XmlDocument has a ChildNodes property of type XmlNodeList. This is really just a collection of XmlNodes. In addition, each XmlNode also has a ChildNodes collection. So, you need to write a function that can progressively deal with each node and its children. It’s a programming technique called recursion, whereby a function repeatedly calls itself, and can be very handy (if a little mind-bending). Go ahead and add this function:

Private Sub ProcessNodes(ByVal nodes As XmlNodeList)

For Each node As XmlNode In nodes xmlList.Items.Add(String.Format( _

"{0} - {1} - {2}", _ node.GetType().Name, node.Name, _ node.Value))

If node.HasChildNodes Then ProcessNodes(node.ChildNodes)

End If

Next

End Sub

The function takes an XmlNodeList as a parameter and then does a simple foreach over the nodes in that collection. For each node, you print out the type of the node, its name in the document, and its value. Finally, if the node has child nodes of its own (something you can check through the HasChildNodes property), you call this function again by passing in the new ChildNodes collection. Simple, really. All you need to do now is add a call to this new function back up in the button’s Click event handler:

Private Sub getXML_Click(ByVal sender As System.Object, _

ByVal e As System.EventArgs) Handles getXML.Click

xmlList.Items.Clear()

Dim xml As String = New WebClient().DownloadString( _ "http://blogs.apress.com/wp-rss2.php")

Dim doc As New XmlDocument() doc.LoadXml(xml)

ProcessNodes(doc.ChildNodes)

End Sub

Run the application now. Click the Get the XML button on the form to see the list box populated, just as in Figure 15-2.

388

C H A P T E R 1 5 W O R K I N G W I T H X M L

Figure 15-2. When you run the application, it shows you detailed information about the XML document it just downloaded.

When the program runs, it displays three things for every item in the XML document: the .NET type of the item found, its name, and its value. As you can see, there are a bunch of .NET types that you’ll need to work with if you choose to do all your XML work directly with XMLDocument. We’re not going to spend too long on this because as I mentioned there are much easier ways to deal with XML. It is worth spending a little time, though, putting all those things into some perspective.

You can see the actual XML document from the Apress blogs site by pointing your web browser at http://blogs.apress.com/wp-rss2.php. It looks like Figure 15-3.

If you run the browser view of the document alongside our application, it’s easy to match what the lister is showing you against what’s actually in the document. The document begins with a <? tag that shows up in the lister as an XmlDeclaration object. Following that there’s a comment tag (<!--), which logically maps to an XmlComment node in our document. The meat of the document follows next. Take a look at the document in IE and you’ll see an RSS tag with attributes that contains a channel tag, which in turn contains title, link, description, pubDate, and a few other tags.

Looking at the lister, you can see that the RSS tag is an XmlElement, as are channel and title. The text inside the title tag is shown as an XmlText node and so on.

Because all the different types of nodes within an XmlDocument all descend from the same XmlNode class, they all have common properties such as Name and Value; our lister application exploits that.

C H A P T E R 1 5 W O R K I N G W I T H X M L

389

Figure 15-3. This is what the RSS feed looks like if you load it into Microsoft Internet Explorer.

Spend time exploring the feed in Internet Explorer and in the application to get a feel for everything in an XmlDocument. When you’re finished, you can move into learning about searching an XmlDocument object.

Searching XML Documents

The standard way to search for something in an XmlDocument object is called XPath. It’s basically a simple language, much like regex is a simple language, that lets you specify a string of characters to uniquely identify something in a document. It basically works like Windows file paths in many ways. For example, to find an element called B that is a child of element A, the XPath would be A/B. You can see the full XPath reference online at http://www.w3.org/TR/xpath, and it’s worth spending the time to read it if you intend

to write a lot of XML manipulation code.

Let’s apply some XPath to our RSS feed document to find and list all the article titles easily.