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

Real - World ASP .NET—Building a Content Management System - StephenR. G. Fraser

.pdf
Скачиваний:
68
Добавлен:
24.05.2014
Размер:
4.59 Mб
Скачать

more efficiently than XmlDocument using XPathNavigator. There is nothing stopping you from using XmlDocument in this scenario; in fact, there is an implementation of XmlReader and XmlWriter that does this. Programmers from Java and MSXML backgrounds will probably continue to use XmlDocument, more for its similarity to what they know than for any other reason.

XmlReader

This abstract class provides the base functionality to read XML data in a forward-only, noncached fashion. It currently has two implementations.

§XmlTextReader: Processes an XML document by tokenizing a textbased stream

§XmlNodeReader: Reads sequentially an in-memory DOM using XmlNodes

XmlReader, when you first look at it, seems a lot like the Simple API for XML (SAX), but actually they are fundamentally different. Whereas SAX uses a more complex push model, XmlReader uses a simple pull model. This means that a developer requests or pulls data one record at a time instead of having to capture the data using event handlers.

Coding using XmlReader seems, to me, more intuitive because you can handle the processing of an XML document as you would a simple file, using a good oldfashioned while loop. There is no need to learn about event handlers or SAX's complex state machine.

XmlWriter

XmlWriter is an abstract class that provides the base functionality to write XML data in a forward-only, noncached fashion. It currently has two implementations.

§XmlTextWriter: Processes an XML document by writing out a textbased stream

§XmlNodeWriter: Writes sequentially into an in-memory DOM using XmlNodes

People who use SAX to write out their XML documents will find XmlWriter to be quite similar.

XPathNavigator

An XmlDocument is an in-memory copy of an entire document's XML. As you saw previously, an XmlDocument can be accessed by the XmlNodeReader and XmlNodeWriter classes, but to get the full benefit of having the entire XML document in memory, it is better to use the XPathNavigator class instead.

XPathNavigator provides much of the same functionality as XmlReader and XmlWriter. In addition, XPathNavigator has the following features:

§It provides random access to the DOM tree.

§It allows the selection of a subset of nodes within the DOM tree for

processing.

For those of you coming from Java or MSXML, XPathNavigator should feel very similar.

XML Examples

You keep hearing how good and easy XML is. After the initial learning bump (there is no real curve), it is actually easy to work with. In the examples that follow, you will explore multiple ways of doing the exact same thing. When you continue and develop your own code, choose the method with which you feel most comfortable because, in most cases, it really doesn't matter which method you use.

Let's see XML coding in action. You will start with three simple examples showing the basics of XML code development: reading, writing, and updating. Then you will launch

into a more complex example that involves implementing a NavBar using an XML document to store the NavBar's navigational structure.

Reading from an XML File

I'll start first with something easy, yet it's probably the most important process in XML coding: the reading of an XML document.

In this example, you will use XmlTextReader to read through the XML document you saw earlier (in Listing 8-1). The remaining examples show three other ways of reading through an XML file.

The first thing you are going to do is create a new project to develop the new Web page. You can use any name you want for your project. I used Ch08Example just to be consistent.

Until now, you have been using only default .NET components to develop your code. For some unknown reason, XML is not a default component. This seems a little weird to me because XML is such an integral part of .NET. Anyway, you now have to add a reference to System.XML.dll to your newly created project because all XML-related code you will need is bundled into it.

Adding an External Reference to a Project

To add an external reference to your project, follow these steps:

1. Select Add Reference from the Project menu. This will display the Add Reference dialog box, as shown in Figure 8-1.

Figure 8-1: The Add Reference dialog box

2.Select System.XML.dll from the component list box.

3.Click the Select button.

4.Click the OK button.

Once you have added a reference to System.XML.dll to your project, you are ready to create the first example. As always, I recommend that you rename the ASPX file and class called WebForm1 to something more meaningful, in this case ReadXML.

The ReadXML Web Page Design

Perform the following steps to design the ReadXML Web page:

1.Give the Web page the title ReadXML.

2.Change the title's format so that it stands out. I changed it to the block format of Heading 3 and changed its color to green.

3.Click and drag a ListBox from the Toolbox onto the Web page and give it a new (ID) of lbReadXML.

4. You might want to resize the list box so you can see more of the XML document it will ultimately display.

Now that you have a display, you might want to create an XML file to display. The first thing I recommend, though it is not essential, is to put your XML files in their own directory. That way, your ASPX files don't get cluttered up with XML files, and it's also easier to locate them.

To create a new directory in Visual Studio .NET:

1.Right -click Ch08Examples in the Solution Explorer.

2.Select New Folder from the Add menu item.

3.Enter XMLFiles into the displayed edit box.

To create a new XML file in Visual Studio .NET:

1.Right -click the XMLFiles folder in the Solution Explorer.

2.Select New Item from the Add menu item. This will display the Add

New Item dialog box, as shown in Figure 8-2.

Figure 8-2: The Add New Item dialog box

3.Click the XML File icon in the Templates window.

4.Enter Content.xml in the Name box.

5.Click the Open button.

6.Enter in the edit window an XML document found in Listing 8-1.

All the preliminary stuff is done. Let's have some fun and do some coding.

Reading an XML File Using XmlTextReader

Open the code for ReadXML in the edit window. Nothing should be new to you. For ReadXML, you need to add the XML namespace. The code is just like adding any other namespace:

using System.Web.UI.HtmlControls;

using System.Xml;

...

From here on, all the code you are going to add will be found within the IsPostBack if statement in the Page_Load() method.

The first thing you need to do is open up the XML stream in an XmlTextReader so that it can be read. The method is quite straightforward. Basically, pass the constructor a stream as a parameter. The code should look like this:

private void Page_Load(object sender, System.EventArgs e)

{

if (!IsPostBack)

{

XmlTextReader reader = new

XmlTextReader("http://localhost/Ch08Examples/XMLFiles/Content.xml");

...

Remember a time when you used to read your files using plain old while statements? You probably wrote one of your first programs using logic like the following:

while (reader.Read())

{

...

}

The Read() method of XmlTextReader parses the XML document into small XML nodes. You should only care about three types of nodes in this example:

§Element: An element of the document. You might also think of this as a tag.

§Text: The text information found between tags.

§EndElement: The closing of an element.

The code in this example is simple. Check the type of node and, if it is one of the types you are interested in, add it to the list box. The following code shows how easy this is:

while (reader.Read())

{

if (reader.NodeType == XmlNodeType.Element)

{

lbReadXML.Items.Add(" <" + reader.LocalName + ">");

}

else if (reader.NodeType == XmlNodeType.Text)

{

lbReadXML.Items.Add("->" + reader.Value);

}

else if (reader.NodeType == XmlNodeType.EndElement)

{

lbReadXML.Items.Add(" </" + reader.LocalName + ">");

}

}

Note that I added some simple formatting in the code to make the list box look more like XML. The Read() method actually strips off all the angle brackets. I also added the arrow to help the text stand out a little more. The final outcome of this example should be a Web page that looks similar to the one shown in Figure 8-3.

Figure 8-3: The ReadXML Web page

Just to make sure that you don't miss anything when you enter this code, Listing 8-2 shows the entire source code for ReadXML.cs.

Listing 8-2: ReadXML.cs

using System;

using System.Collections;

using System.ComponentModel;

using System.Data;

using System.Drawing;

using System.Web;

using System.Web.SessionState;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.HtmlControls;

using System.Xml;

namespace Ch08Examples

{

public class ReadXML : System.Web.UI.Page

{

protected System.Web.UI.WebControls.ListBox lbReadXML;

private void Page_Load(object sender, System.EventArgs e)

{

if (!IsPostBack)

{

// Read using XmlReader

XmlTextReader reader = new XmlTextReader(

"http://localhost/Ch08Examples/XMLFiles/Content.xml");

while (reader.Read())

{

if (reader.NodeType == XmlNodeType.Element)

{

lbReadXML.Items.Add("<" + reader.LocalName + ">");

}

else if (reader.NodeType == XmlNodeType.Text)

{

lbReadXML.Items.Add("->" + reader.Value);

}

else if (reader.NodeType == XmlNodeType.EndElement)

{

lbReadXML.Items.Add("</" + reader.LocalName + ">");

}

}

}

}

#region Web Form Designer generated code override protected void OnInit(EventArgs e)

{

InitializeComponent();

base.OnInit(e);

}

private void InitializeComponent()

{

this.Load += new System.EventHandler (this.Page_Load);

}

#endregion

}

}

Writing to an XML File

Great, you can read an XML file. Now, how do you get a program to write one? The process is so simple that I decided to also provide you with another way of reading XML files.

Using the same project, create a new Web form and call it WriteXML.aspx. Keep all the examples in the same project because you will be using them again in the final example of the chapter.

Design your Web page exactly the same way you did in the first example. The only differences should be the Web page title (for obvious reasons) and the (ID) of the list box, which you should change to lbXPath.

Now bring up the code for WriteXML in the main edit window and you can get started. The first thing you have to do is add the namespace for XML, as you would for any XML coding endeavor. You will also have to add the XPath namespace so that you can access the XPathNavigator. The code should look like this:

using System.Web.UI.HtmlControls;

using System.Xml;

using System.Xml.XPath;

...

The next step is to open up an XML stream in an XmlTextWriter so that it can be (you guessed it) written to. The constructor is pretty simple. All you need to provide it is the stream where you want the XML document to be written and the encoding you want the stream to have. Use null because it writes out UTF-8, which is sufficient in most cases. To add a little excitement to this method, I decided to implement it using the Server.MapPath() method. This helpful little method will convert the virtual path of the Web page's directory and replace it with the physical location. For example:

http://localhost/Ch08Examples/XMLFiles/MyContent.xml

gets converted to the following (on my computer):

C:\Inetpub\wwwroot\Ch08Examples\XMLFiles\MyContent.xml

This method is not really needed, but I threw it in for grins and giggles. Here is the constructor code:

if (!IsPostBack)

{

XmlTextWriter writer = new XmlTextWriter(

Server.MapPath("XMLFiles/MyContent.xml"),

null);

...

The first thing you will note when XmlTextWriter writes out the XML document is that it is unformatted. In fact, it comes out as one long line with no breaks. This is fine for a computer, but for a human, it is not the most pleasant format. To fix this, XmlTextWriter provides a few formatting properties. You can look them up in the

.NET documentation provided by Visual Studio .NET. This example, to make the XML document more human-friendly, adds the following formatting code:

writer.Formatting = Formatting.Indented;

writer.Indentation = 2;

Okay, now let's get down to writing the XML. The first thing you need to do is start the document using the WriteStartDocument() method. This method adds the following standard XML header to the XML document:

<?xml version="1.0" encoding=" utf-8"?>

Next, you simply write the XML document. The only real difference (at least with a simple XML document) between real XML and the code is that the WriteStartElement and WriteEndElement method calls replace the angle brackets. Once you have finished adding the XML document, you finish off with a WriteEndDocument() method. The following code snippet shows how easy writing XML really is:

//start XML document writer.WriteStartDocument();

//Write XML document writer.WriteStartElement("", "Content", "");

writer.WriteStartElement("", "ContentForAuthor", ""); writer.WriteStartElement("", "Author", ""); writer.WriteStartElement("", "FirstName", ""); writer.WriteString("John"); writer.WriteEndElement(); writer.WriteStartElement("", "LastName", ""); writer.WriteString("Doe");

writer.WriteEndElement();

writer.WriteEndElement(); writer.WriteStartElement("", "Articles", ""); writer.WriteStartElement("", "Headline", ""); writer.WriteString("This is the Headline"); writer.WriteEndElement(); writer.WriteStartElement("", "Story", ""); writer.WriteString("The story is entered here.");

//not needed as XmlTextWrite closes all open elements

//with WriteEndDocument

//writer.WriteEndElement();

//writer.WriteEndElement();

//writer.WriteEndElement();

//writer.WriteEndElement();

//End XML document

writer.WriteEndDocument();

Now that you have a new XML document, you must close up the stream so that some other process can access it (in this case, so that the document can be read into the list box using XPathNavigator). The Close() method should not surprise anyone:

writer.Close();

Because that was too easy, let's explore another way to read XML files. This method loads the entire document into memory and then uses a random access navigator to move through the document. This process is a little more complex because you have to be aware of the recursive structure of an XML file and you must navigate using it. On the other hand, this method is very powerful because you can access a node randomly, unlike with XmlTextReader, which only works in a forward direction.

First, open up an XPathDocument, load it into memory, create an XPathNavigator to the in-memory document, move the navigation point to the root of the document, and display the XML document as shown in this code:

XPathDocument doc = new XPathDocument(

new XmlTextReader(

"http://localhost/Ch08Examples/XMLFiles/MyContent.xml"));

XPathNavigator nav = doc.CreateNavigator();

nav.MoveToRoot();

DisplayXMLTree(nav);

Now comes the fun part. You need to write a recursive method if you want to completely navigate the document tree. The following code snippet shows the recursive method that simply checks for child nodes and, if it finds one, calls itself to see whether the child has children, and so on. Once there are no more children, it finds its way back up to the parent and then looks for a parent's sibling. If it finds one, it calls itself so that it can process the sibling's children.

private void DisplayXMLTree (XPathNavigator nav)

{

if (nav.HasChildren)

{

nav.MoveToFirstChild();

FormatXML (nav);

DisplayXMLTree (nav);

nav.MoveToParent();

lbXPath.Items.Add(" </" + nav.Name + ">");

}

while (nav.MoveToNext())

{

FormatXML (nav);

DisplayXMLTree (nav);

}

}

The FormatXML() method simply adds the node information to the list box so that you can see that it works. If it doesn't have children, the navigation point points to some text; otherwise, it points to an element. The code formats the node to look like XML. As with XmlTextReader, the angle brackets are not stored.

private void FormatXML (XPathNavigator nav)

{

if (!nav.HasChildren)

{

lbXPath.Items.Add(" ->" + nav.Value);

}

else

{

lbXPath.Items.Add(" <" + nav.Name + ">");

}

}

Listing 8-3 shows the entire WriteXML.cs.

Listing 8-3: WriteXML.cs

using System;

using System.Collections;

using System.ComponentModel; using System.Data;

using System.Drawing; using System.Web;

using System.Web.SessionState; using System.Web.UI;

using System.Web.UI.WebControls; using System.Web.UI.HtmlControls; using System.Xml;

using System.Xml.XPath; namespace Ch08Examples

{

public class WriteXML : System.Web.UI.Page

{

protected System.Web.UI.WebControls.ListBox lbXPath;

private void DisplayXMLTree (XPathNavigator nav)

{

if (nav.HasChildren)

{

nav.MoveToFirstChild(); FormatXML (nav);

Соседние файлы в предмете Программирование