asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search








Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Reading and Writing XML in .NET Version 2.0 - Part 2
By Alex Homer
Rating: 4.0 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Table of Contents

    • Part 1 - Using XmlReaderSettings, XmlReader, and the Static Create Methods
    • Part 2 - Using XmlWriterSettings, XmlWriter, and the Static Create Methods
    • Part 3 - Loading and Persisting XML with an XML Document Store Object

    "Using XmlWriterSettings, XmlWriter, and the Static Create Methods"

     

    This is the second in a series of three articles that look in detail at how the new features of the XmlReader and XmlWriter classes in version 2.0 of the .NET Framework can be used to read and write XML documents, and interact with the new XML document store objects. The topics covered in the previous article are:

     

    • The new "settings" classes and static Create methods for XmlReader and XmlWriter
    • Creating and using an XmlReader to read and validate XML documents and fragments
    • Some of the useful new features of the XmlReader class

     

    In this article, we move on to look at the XmlWriter and XmlWriterSettings classes, and how they can be used to write XML documents and fragments more easily and more efficiently than in version 1.x of .NET. The topics we'll be covering are:

     

    • Using the XmlWriterSettings class to generate XmlWriter instances
    • Using an XmlWriter to write XML documents and fragments
    • Controlling the output format and encoding of the XML document
    • Streaming XML through an XmlReader and XmlWriter
    • Some of the useful new features of the XmlWriter class

     

    As in the previous article, we'll look into the issues involved in using the new classes, the reasoning behind the changes, and how the new features simplify your code and provide better overall efficiency for your applications.

    The XmlWriterSettings Class

    The previous article discussed the concepts behind the new "settings" classes for XmlReader and XmlWriter. The two new classes named XmlReaderSettings and XmlWriterSettings can be used to maintain a consistent set of behaviors when generating instances of readers and writers on demand, without having to repeatedly set their properties. This has several benefits in that it:

     

    • Reduces the code you have to write
    • Allows the framework to make optimizations in the reader or writer based on the settings, for example omitting validation support if this is not required
    • Provides classes that can execute more efficiently in circumstances where the extra features are not required
    • Allows you to create instances of the abstract base classes, rather than having to instantiate classes that inherit from XmlReader or XmlWriter
    • Allows the XmlReader and XmlWriter to be extended in future releases without breaking your code, and therefore removes the need for multiple concrete implementations aimed at different scenarios

     

    The "settings" classes are used in the new static Create method, of the XmlReader and XmlWriter classes, as demonstrated in the previous article. So, having seen how you use an XmlReaderSettings instance to specify the behavior of an XmlReader, the way you use the XmlWriterSettings class will be obvious. Of course, XmlWriter has a different set of properties compared to XmlReader, and these properties are reflected in the XmlWriterSettings class. Figure 1 shows the XmlWriterSettings class, and you can see that some of the properties are the similar to XmlReaderSettings. There is a CheckCharacters property that controls whether illegal XML characters are permitted, and a CloseOutput property that automatically closes the underlying output stream when the writer is closed.

     

    Figure 1 - The XmlWriterSettings Class

     

    You can specify if the elements in the output are placed on a new line and indented, whether each attribute is placed on new line, and the characters that are used for the indentation and the line breaks. Even more control over the output format is provided by the NewLineHandling enumeration. By default, any new line characters between elements and attributes in the document are replaced by the standard Windows new line characters \r\n (i.e. the default is NewLineHandling.Replace). However, you can turn off this replacement using the value NewLineHandling.None, or specify that the original new line characters are preserved (except that new line characters separating attributes are replaced by a single space) using the value NewLineHandling.Entitize.

     

    Like XmlReader, you can specify the conformance level for an XmlWriter so that it will generate output that is not actually a complete XML document when you only want to write fragments of XML. For example, as you'll see shortly, you can create XML fragments that contain multiple root nodes.

     

    If you are using the XmlWriter to stream output from an XSL-T transformation, using the new XslCompiledTransform class, the read-only OutputMethod property indicates the format of the output that is generated by the writer. This is a value from the XmlOutputMethod enumeration shown in Figure 1, allowing you to detect whether the output is serialized as HTML, XML, or just the text content is serialized.

     

    Finally, the XmlWriterSettings class exposes a reference to an Encoding class instance that specifies the encoding to be applied to the document that is generated. The default is System.Encoding.UTF8, but you can change this to suit the requirements of your application. Some of the ways that you can use the XmlWriterSettings class are discussed next.

    Creating an XmlWriter Using the XmlWriterSettings Class

    To create an XmlWriter instance, you first instantiate an instance of the XmlWriterSettings class, set the properties you want, and the call the Create method of the XmlWriter class. For example, this code creates an XmlWriter that checks for invalid characters in the XML you write, and closes the underlying stream when the reader is closed. Notice how we use the new Using construct to ensure that the writer is correctly disposed at the end of the process. This ensures that the XmlWriter is closed, even if we forget to call the Close method (the Using construct was available in C# in version 1.1, and is now available in VB.NET in version 2.0):

     

    Dim ws As New XmlWriterSettings()

    ws.CheckCharacters = True

    ws.CloseOutput = True

    Using xw As XmlWriter = XmlWriter.Create(sFilePath, ws)

      Try

        ' ... create the XML document here ...

        xw.Close()

      Catch ex As Exception

        ' ... display error details ...

      End Try

    End Using

     

    You can, of course, create the XmlWriter without taking advantage of the Using method, for example if you want to return it from a function so that it can be accessed from elsewhere in your application. The function shown next creates an XmlWriter using the static Create method, taking as parameters a reference to an XmlWriterSettings instance and a Stream for the output to be sent to:

     

    Function GetXmlWriter(ws As XmlWriterSettings, outStream As Stream) As XmlWriter

      Dim xw As XmlWriter = Nothing

      Try

        xw = XmlWriter.Create(outStream, ws)

        Return xw

      Catch ex As Exception

        Try

          xw.Close()

        Catch

        End Try

        Return Nothing

      End Try

    End Function

     

    You could then use this function like this:

     

    Dim settings As New XmlWriterSettings()

    settings.CheckCharacters = True

    settings.CloseOutput = True

    ' write an XML document to the ASP.NET Response

    Dim webWriter As XmlWriter = GetXmlWriter(settings, Response.OutputStream)

    If Not (webWriter Is Nothing) Then

      ' ... create the XML document here ...

      webWriter.Close()

    End If

    ...

    ' write an XML document to the screen

    settings.Indent = True

    settings.Encoding = Encoding.ASCII

    Dim screenWriter As XmlWriter = GetXmlWriter(settings, Console.OpenStandardOutput())

    If Not (screenWriter Is Nothing) Then

      ' ... create the XML document here ...

      screenWriter.Close()

    End If

     

    Creating an XML Document with an XmlWriter

    Once you've created the XmlWriter, you can use it to generate the output you need. The XmlWriterin version 2.0 supports pretty much the same set of methods for writing XML elements, attributes, comments, declaration, processing instructions, etc., as the version 1.xXmlWriter class. So you can create a simple XML document, once you've created the XmlWriter, like this:

     

    ...

    xw.WriteStartDocument(True)

    xw.WriteComment("Created at " & DateTime.Now.ToString("hh:mm:ss"))

    xw.WriteStartElement("root-node")

    xw.WriteElementString("child-node", "The element value")

    xw.WriteStartElement("next-child")

    xw.WriteAttributeString("some-attribute", "A value")

    xw.WriteAttributeString("another-attribute", "Another value")

    xw.WriteValue("The next element value")

    xw.WriteEndElement()

    xw.WriteEndDocument()

    xw.Close()

     

    This creates an XML document containing a root node and two child nodes, with two attributes on the second child node. The result is:

     

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

    <!--Created at 13:37:46-->

    <root-node>

      <child-node>The element value</child-node>

      <next-child

        some-attribute="A value"

        another-attribute="Another value">The next element value</next-child>

    </root-node>

     

    Note how the WriteStartElement and WriteElementString methods allow you to create the nested hierarchy. The WriteStartElement method creates the opening element tag, and you then populate the element using the WriteValue, WriteChars or WriteString method. Calling WriteEndElement automatically closes the most recently opened element by writing the appropriate end tag. The WriteElementString method generates a complete element, including the opening and closing tags. Similar methods named WriteStartAttribute, WriteEndAttribute and WriteAttributeString allow you to add attributes to the elements as they are created.

     

    The WriteStartDocument method prepares the writer and generates the opening <?xml version="1.0"?> declaration, while the WriteEndDocument method automatically closes all open elements in the correct order and resets the writer. Other methods of the XmlWriter class (and there are lots of them) include WriteDocType (which creates a !DOCTYPE declaration), WriteComment, WriteCData (which creates a [!CDATA] section), WriteCharEntity, WriteEntityRef, WriteProcessingInstruction and WriteWhitespace. Look up "XmlWriter methods" in the Help file or SDK for a full list and descriptions of each one.

     

    Writing Namespaces and Qualified Names

    Most of the XML documents you generate will need to include namespace declarations, and the XmlWriter provides support for this in all of the "write" methods that generate elements and attributes. These methods accept a String parameter that is the namespace URI within which the element or attribute will live. If the document contains a declaration of a namespace prefix for that URI, the methods automatically use the prefix when generating the element or attribute by pre-pending it to the local name.

     

    You can see how this works using the example page we provide, named xmlwritersettings.aspx. This page, shown in Figure 2, demonstrates many of the features of the XmlWriterSettings and XmlWriter class that we discuss in this article. You can run or download all of the samples from our Website at http://www.daveandal.net/articles/readwritexml/.

     

     

    Figure 2 - The XmlWriterSettings and XmlWriter Example Page

     

    We'll look at the various option settings in the page shortly, but for the moment concentrate on the XML document that is generated by the page. This contains a default namespace on the root-node element, as well as the declaration of a namespace prefix "qn" that represents a different namespace. The last element within the root-node element uses this namespace prefix to place it within in the second namespace. Generating this kind of multi-namespace XML document is easy using the XmlReader - you just need to be aware of a few issues that affect the generated output.

    Generating Default Namespace Declarations

    The first point to note is when you want to apply a default namespace using the xmlns attribute without a namespace prefix declaration. Following the rules of XML, the root node of your document also lives in this namespace, but the namespace is not declared when you call the WriteStartElement method to create the opening tag for the root element. Therefore you must specify this namespace when you call the WriteStartElement method:

     

    xw.WriteStartElement("root-node", "http://testdemo")

     

    Then you can add the xmlns attribute if you wish, but in fact it's not necessary because the XmlWriter detects that you are now in a new namespace and add the attribute xmlns="http://testdemo" to the element automatically. If you look at the source code for the example page (there is a [view source] link at the bottom of the page), you'll see this in the code comments.

     

    The same process occurs if you call WriteStartElement or WriteElementString and specify a new namespace. The XmlWriter automatically adds an xmlns attribute to the element so that it is the new default namespace for the enclosed XML content:

     

    xw.WriteElementString("child-node", "http://testdemo/children", "The element value")

     

    This creates the element child-node as:

     

    <child-node xmlns="http://testdemo/children">The element value</child-node>

     

    To "escape" from this namespace, and return to the previous namespace, you use the WriteFullEndElement method.

    Generating Namespace Prefix Declarations and Qualified Elements

    If you look back at Figure 2, you'll see that the last element in the document contains the prefix "qn":

     

    <qn:qualified-node>Another element value</qn:qualified-node>

     

    This namespace prefix is declared in the root-node element as:

     

    <root-node xmlns:qn="http://testdemo/names" xmlns="http://testdemo">

     

    To generate this namespace declaration, we first use the technique described above to generate the root-node element with the default namespace xmlns="http://testdemo", then use the overload of the WriteAttributeString method that accepts four parameters to specify the xmlns attribute name, the namespace prefix qn, omit the namespace for this attribute (so it lives in the default namespace and therefore has no prefix), and the value for this attribute - the namespace we want to associate with the new prefix:

     

    xw.WriteStartElement("root-node", "http://testdemo")

    xw.WriteAttributeString("xmlns", "qn", Nothing, "http://testdemo/names")

     

    Now we can generate elements that use the new namespace prefix simply by specifying the namespace when we call the WriteElementString or WriteAttributeString method:

     

    xw.WriteElementString("qualified-node", "http://testdemo/names", "Another element value")

     

    However, the new overload of the WriteElementString method added to the XmlWriter in version 2.0 allows you to generaqte elements in a separate namespace in a single operation - without having to add the namespace prefix declaration to the root node if this suits the document format you want. This overload accepts four String values: the namespace prefix, the element name, the

    Namespace URI and the element value - for example:

     

    xw.WriteElementString("mqn", "qtwo-node", "http://testdemo/morenames", "Some value")

     

    This generates an element containing both the namespace prefix and the declaration of that prefix, placing this element into that namespace without changing the default namespace:

     

    <mqn:qtwo-node xmlns:mqn="http://testdemo/morenames">Some value</mqn:qtwo-node>

    Controlling the Output Format

    The example page shown in Figure 2 contains the results of writing the XML document. In that figure, the document occupies multiple lines separated by carriage returns and is indented to make it easy to see what it contains. However, this is not the default format for the output from an XmlWriter. Unless you like to sit and admire your elegantly formatted XML documents in a text editor, the fact that they contain non-significant white-space (such as multiple spaces, tabs and carriage returns) between each element is irrelevant. In effect, XML is a stream of characters, with the data delimited by the node tags and a single space between each attribute. 

     

    The reason that Figure 1 shows the XML with carriage returns and indents is because we set these two options using the checkboxes at the top of the page - making it easy to see what the XML contains. Without it, the XML is displayed on a single line that scrolls off to the right of the browser window.

     

    The XmlWriterSettings class exposes four properties that you can use to specify the formatting of the XML that is generated by the XmlWriter(s) you create from it. You can experiment with these in the example page - Figure 3 shows the effects of the following settings:

     

    ' indent the output and insert line breaks

    ws.Indent = True

    ' start each attribute on a new line

    ws.NewLineOnAttributes = True

    ' use a Tab for indents instead of the default two spaces

    ws.IndentChars = ControlChars.Tab

    ' use two Return characters instead of one

    ws.NewLineChars = ControlChars.CrLf & ControlChars.CrLf

     

     

    Figure 3 - Applying Indenting and Custom NewLine Characters with an XmlWriterSettings Instance

     

    You can also control whether the <?xml version="1.0"?> declaration is generated - in some cases you may want to omit this. For example, if you are generating output from multiple writers to create a compound document, you will only want the declaration to appear once at the start of the document. The example page contains a checkbox where you can set the OmitXmlDeclaration property of the XmlReaderSettings instance to True to see this in action.

    Writing XML Fragments

    As well as generating well-formed XML documents, you can use the XmlWriter to create fragments that are not - on their own- well-formed XML. This simply involves setting the ConformanceLevel property of the XmlWriterSettings instance to ConformanceLevel.Fragment:

     

    ws.ConformanceLevel = ConformanceLevel.Fragment

     

    However, there is an issue to be aware of in this case. You cannot call the WriteStartDocumentor WriteEndDocument method when you use ConformanceLevel.Fragment. And, as the WriteStartDocument method generates the XML declaration, this means that you will not get <?xml version="1.0"?>  at the start of the output (you would not include this anyway if the fragment is not a well-formed document). The code in our example page checks the value of the ConformanceLevel property, and does not call WriteStartDocument or WriteEndDocument if a fragment is being generated. However, it does add a second element at the root level of the document to prove that you can create fragments that are not well-formed documents:

     

    If ws.ConformanceLevel <> ConformanceLevel.Fragment Then

      ' cannot call WriteStartDocument for an XML fragment

      xw.WriteStartDocument(True)

    End If

    ... write contents of document here as before ...

    If ws.ConformanceLevel = ConformanceLevel.Fragment Then

      ' add a second root node, this is illegal in a valid document

      xw.WriteElementString("another-root-node", "This is a now a fragment")

    Else

      ' cannot call WriteEndDocument for an XML fragment

      xw.WriteEndDocument()

    End If

     

    Figure 4 shows the results. You can see the fragment with its two root nodes, and there is no XML declaration at the start:

     

    Figure 4 - Creating an XML Fragment with an XmlWriterSettings and XmlWriter

    Specifying the Output Encoding

    The final feature that our example page demonstrates is how you can set the encoding of the XML documents you create with the XmlWriterSettings and XmlWriter classes. The default encoding for XML document created this way is UTF-8. The XmlWriter uses an instance of the UTF8Encoding class to encode the output, so that it is suitable for use in almost all XML parsers, and in Web Services and other applications.

     

    However, you can use the Encoding property of the XmlWriterSettings class to specify an alternative encoding if you wish. The drop-down list in the example page contains six values: ASCII, UTF7, UTF8, UTF32, Unicode (equivalent to UTF-16), and BigEndianUnicode. These correspond to the encoding classes available in the .NET Framework, and the code in the page applies the one you select (when you also set the checkbox in the page) using the static properties of the Encoding class:

     

    If chkEncoding.Checked Then

      Select Case lstEncoding.SelectedItem.Text

        Case "ASCII"

          ws.Encoding = Encoding.ASCII

        Case "UTF7"

          ws.Encoding = Encoding.UTF7

        Case "UTF8"

          ws.Encoding = Encoding.UTF8

        Case "UTF32"

          ws.Encoding = Encoding.UTF32

        Case "Unicode"

          ws.Encoding = Encoding.Unicode

        Case "BigEndianUnicode"

          ws.Encoding = Encoding.BigEndianUnicode

      End Select

    End If

     

    If you run the example, and try different values, you'll see the encoding in the opening XML declaration. Notice that, because the Web browser automatically translates most encodings into the same visual output (see Figure 5), you don’t see any other difference except where you select "UTF7" - which the browser cannot translate!

     

    Figure 5 - Specifying the Encoding with an XmlWriterSettings and XmlWriter

     

    Streaming XML from an XmlReader to an XmlWriter

    The XmlReader is really just a pull-model parser that exposes the XML as a stream. Meanwhile, the XmlWriter is an object that converts a stream into another format or persists it to another object. For example, an XmlReader can take its input from a disk file, a stream or another reader instance; while the XmlWriter can generate its output as a disk file, a stream, a StringBuilder or another writer instance. This means that you can link the XmlReader and XmlWriter together so that, as you read nodes from the XmlReader, you generate the output you require through the XmlWriter.

     

    Why is this useful? Well, one particular case is when working with very large XML documents that you don’t want to load into memory using a document store object such as XmlDocument. It's also very efficient, which is useful if - for example - you just need to modify the occasional value in the XML or perform some kind of transformation process or business logic. Of course, taking this to its logical conclusion, the XmlReader and XmlWriter can also be used as the input and output vehicles for other classes such as XslCompiledTransform, in which case you hand off the actual processing of the XML to another object instead. In the next section, you'll see an example of streaming XML, along with some of the other useful new features of the XmlWriter class.

    Page 2 -->

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Supporting Products/Tools
    Stonebroom.ASP2XML
    Stonebroom.ASP2XML(c) is an interface component designed to make building applications that transport data in XML format much easier. It can be used to automatically pass updates back to the original data source.
    [Top]
    Other Articles
    Sep 22, 2005 - Implementing Remote Calling Without Using AJAX
    Right now the latest buzzword around town is AJAX. AJAX is an acronym for Asynchronous JavaScript and XML and is a method used to implement remote calling. The problem is that AJAX is only implemented in ASP.NET 2.0. This article will show you one way to implement remote calling without using AJAX or the XMLHttpRequest object. The technique outlined can even be used from classic ASP and is sufficient for most remote calling needs.
    [Read This Article]  [Top]
    Aug 18, 2005 - SQL Server 2005 XQuery and XML-DML - Part 3
    This article is the third and final installment of Alex Homer's series covering the new XML support in Microsoft SQL Server 2005. In it he covers updating the contents of xml columns, comparing traditional XML update techniques with XQuery, and using XQuery in a managed code stored procedure.
    [Read This Article]  [Top]
    Aug 11, 2005 - SQL Server 2005 XQuery and XML-DML - Part 2
    In the second part of his series on SQL Server 2005's new XML support, Alex Homer looks at extracting data from XML columns, comparing traditional XML data access approaches with XQuery, and combining XQuery and XSL-T.
    [Read This Article]  [Top]
    Aug 3, 2005 - SQL Server 2005 XQuery and XML-DML - Part 1
    Microsoft SQL Server 2005 now offers great support for and close integration with XML as a data persistence format. In the first article of his series examining this new support, Alex Homer offers an overview of how SQL Server 2005 stores XML documents and schemas, examines how it supports querying and manipulating XML documents, and provides a simple test application that allows you to experiment with XQuery.
    [Read This Article]  [Top]
    Jun 30, 2005 - Reading and Writing XML in .NET Version 2.0 - Part 3, Cont'd
    In the final article of his series on reading and writing XML in .NET 2.0, Alex Homer looks at how the updated XML document store objects XmlDocument, XmlDataDocument and PathDocument can be used to read, persist and write XML documents and fragments more easily and more efficiently than in .NET 1.x.
    [Read This Article]  [Top]
    Jun 29, 2005 - Reading and Writing XML in .NET Version 2.0 - Part 3
    In the final article of his series on reading and writing XML in .NET 2.0, Alex Homer looks at how the updated XML document store objects XmlDocument, XmlDataDocument and PathDocument can be used to read, persist and write XML documents and fragments more easily and more efficiently than in .NET 1.x.
    [Read This Article]  [Top]
    Jun 16, 2005 - Reading and Writing XML in .NET Version 2.0 - Part 2, Cont'd
    Alex Homer continues his series on reading and writing XML in .NET 2.0. In part one, we focused on the reading side of things, examining the XmlReader and XmlReaderSettings classes. In this article, we move on to look at the XmlWriter and XmlWriterSettings classes, and how they can be used to write XML documents and fragments more easily and more efficiently than in version 1.x of .NET.
    [Read This Article]  [Top]
    Jun 2, 2005 - Reading and Writing XML in .NET Version 2.0 - Part 1, Cont'd
    In the first part of his series on reading and writing XML in .NET 2.0, Alex Homer discusses the XmlReader and XmlReaderSettings classes. The XmlReader exposes several useful new features and the all new XmlReaderSettings class makes it easy to generate single or multiple instances of an XmlReader with a range of useful properties.
    [Read This Article]  [Top]
    Jun 1, 2005 - Reading and Writing XML in .NET Version 2.0 - Part 1
    In the first part of his series on reading and writing XML in .NET 2.0, Alex Homer discusses the XmlReader and XmlReaderSettings classes. The XmlReader exposes several useful new features and the all new XmlReaderSettings class makes it easy to generate single or multiple instances of an XmlReader with a range of useful properties.
    [Read This Article]  [Top]
    May 26, 2005 - Implementing AJAX Using ASP.NET 1.1
    AJAX is an acronym that stands for Asynchronous JavaScript and XML. AJAX's strong point is that it allows data on a page to be dynamically updated without the browser having to reload the page. This article offers a brief introduction and description of AJAX and then provides some sample code illustrating its usage.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry



    JupiterOnlineMedia

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info


    Legal Notices, Licensing, Reprints, & Permissions, Privacy Policy.

    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers

    Solutions
    Whitepapers and eBooks
    Microsoft Article: Will Hyper-V Make VMware This Decade's Netscape?
    Microsoft Article: 7.0, Microsoft's Lucky Version?
    Microsoft Article: Hyper-V--The Killer Feature in Windows Server 2008
    Avaya Article: How to Feed Data into the Avaya Event Processor
    Microsoft Article: Install What You Need with Windows Server 2008
    HP eBook: Putting the Green into IT
    Whitepaper: HP Integrated Citrix XenServer for HP ProLiant Servers
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 1
    Intel Go Parallel Portal: Interview with C++ Guru Herb Sutter, Part 2--The Future of Concurrency
    Avaya Article: Setting Up a SIP A/S Development Environment
    IBM Article: How Cool Is Your Data Center?
    Microsoft Article: Managing Virtual Machines with Microsoft System Center
    HP eBook: Storage Networking , Part 1
    Microsoft Article: Solving Data Center Complexity with Microsoft System Center Configuration Manager 2007
    MORE WHITEPAPERS, EBOOKS, AND ARTICLES
    Webcasts
    Intel Video: Are Multi-core Processors Here to Stay?
    On-Demand Webcast: Five Virtualization Trends to Watch
    HP Video: Page Cost Calculator
    Intel Video: APIs for Parallel Programming
    HP Webcast: Storage Is Changing Fast - Be Ready or Be Left Behind
    Microsoft Silverlight Video: Creating Fading Controls with Expression Design and Expression Blend 2
    MORE WEBCASTS, PODCASTS, AND VIDEOS
    Downloads and eKits
    Sun Download: Solaris 8 Migration Assistant
    Sybase Download: SQL Anywhere Developer Edition
    Red Gate Download: SQL Backup Pro and free DBA Best Practices eBook
    Red Gate Download: SQL Compare Pro 6
    Iron Speed Designer Application Generator
    MORE DOWNLOADS, EKITS, AND FREE TRIALS
    Tutorials and Demos
    How-to-Article: Preparing for Hyper-Threading Technology and Dual Core Technology
    eTouch PDF: Conquering the Tyranny of E-Mail and Word Processors
    IBM Article: Collaborating in the High-Performance Workplace