An Introduction to the XML Tools in Visual Studio 2005

 

Neetu Rajpal
Microsoft Corporation

July 2004

Applies to:
   Microsoft Visual Studio 2005
   XML/XSL
   XML Editing and XSLT debugging functionality in Visual Studio 2005

Summary: This article is an introduction to the XML Editor and the XSLT Debugger in Visual Studio 2005 (formerly known by the codename "Whidbey"). (13 printed pages)

Contents

Introduction
Creating and Editing an XML file Using the XML Editor
Inferring a Schema from an XML document
Attaching an XML Schema to an XML Document
Editing XSLT
Debugging XSLT Files
Conclusion

Introduction

With wider adoption of XML, XSLT, XSD Schemas, and other applications, XML is being touched by developers at various places of the application. This mainstreaming of XML requires that developers be supported with better development tools. Visual Studio 2005 significantly improves the XML editing and XSLT Debugging experiences.

The XML editor includes the following functionality:

  • Design time well-formedness and validation errors.
  • Validation support for Schema, DTD, and XDR.
  • Inferring an XSD Schema from an XML instance.
  • Converting a DTD or XDR to XSD Schema.
  • Context-sensitive Intellisense.
  • XSLT editing, viewing the results of the transform.
  • Standard Visual Studio code-editing, such as outlining and commenting or un-commenting.

The XSLT debugger comprises the following functionality:

  • Invoking the debugger from the XML Editor.
  • The ability to set and remove breakpoints.
  • Standard Visual Studio debugger function key and menu bindings (F9 for setting/removing breakpoints, F11 for "Step In," and so on).
  • Viewing the output of the transform as it is being generated.
  • Locals, Watch, and Call stack windows.
  • Stepping into the XSLT from a C# (or any other CLR language) program.

The remainder of this article will explain the above listed features in more detail, and will also be a mini-tutorial for the XML Editor and the XSLT Debugger.

Creating and Editing an XML File Using the XML Editor

To create an XML file, simply select the File->New menu option in Visual Studio 2005 and select the "XML File" template from the list presented. To open an existing XML file, select File->Open. An XML file can be added to an existing project or solution by using the Add Existing (or Add New) Item option from the context menu. Any XML file (such as .config) that does not have a default editor associated to it in Visual Studio will be opened in the XML Editor.

Once the user starts editing, the XML editor checks the well-formedness errors in the XML and provides live feedback to the user via two mechanisms. In the example in the screen shots below, the <root> tag is not closed, the end tag for <element> tag does not match, and so on.

The first mechanism is the red squiggly under the sequence of characters that is the cause of the errors. If the user's mouse pointer hovers over the section with the error, a tool tip will provide the actual error text (figure 1).

The second way the error information is provided is through the error list. The Visual Studio Error List (available from the View menu command) is populated with the error message text and the position information of the error. Double-clicking on an error in this list would place the user's cursor at the exact location of the error (figure 2).

Click here for larger image.

Figure 1. Well formed errors are underlined with red squiggly lines

Figure 2. Well formed errors in the XML are also listed in the Visual Studio Error List

If the XML File being edited has an XSD Schema, DTD, or XDR association, the XML editor provides design time validation and, just like when checking well-formedness, reports errors by means of two mechanisms.

The first mechanism is the blue squiggly under the "invalid" XML content (figure 3). Populating the warning portion of the Error List is the second mechanism (figure 4).

Figure 3. Validation errors are underlined with blue squiggly lines

Figure 4. Validation errors in the XML are also listed in the Visual Studio Error List as warnings

When editing a file that has a schema attached to it, the XML editor provides context-sensitive Intellisense. In the example below (figure 5), the drop down list contains name as the only valid element to include under customer, because the schema for the customer element is declared to have a sequence of two elements: name and address.

Figure 5. Context-sensitive Intellisense based on the Schema file

Inferring a Schema from an XML Document

Consider a scenario in which the user gets some XML from somewhere, and is now required to create a schema for it. This can happen in a data aggregation scenario, where recipients have less power in the deal and will have to accommodate the sender's XML, which might not have a schema. Recipients might still need a schema so they can deserialize the incoming XML into C# objects. The Visual Studio XML Editor can help make easier this schema generation from an XML document process.

The Create Schema menu command on the XML Editor will infer a schema based on the XML instance. The XML instance below contains one "customers" tag, which contains multiple customer child nodes. The customer node itself has a sequence of name and address nodes. By issuing the Create Schema command from the XML menu or from the XML toolbar, the user can create a schema that looks like the inferred schema below.

Instance

<?xml version="1.0" encoding="utf-8" ?> 
<customers xmlns:ns1="MyCustomerInfo">
    <customer>
        <name> John Doe</name>
        <address> Some City, USA</address>
    </customer>
    <customer>
        <name> Jane Doe </name>
        <address> Some City, USA</address>
    </customer>
</customers>

Inferred Schema

<?xml version="1.0" encoding="utf-8"?>
<xs:schema 
   xmlns:ns1="MyCustomerInfo" 
   attributeFormDefault="unqualified" 
   elementFormDefault="qualified" 
   xmlns:xs="http://www.w3.org/2001/XMLSchema">

    <xs:element name="customers">
        <xs:complexType>
            <xs:sequence>
                <xs:element maxOccurs="unbounded" name="customer">
                    <xs:complexType>
                        <xs:sequence>
                            <xs:element name="name" type="xs:string" />
                            <xs:element name="address" type="xs:string" />
                        </xs:sequence>
                    </xs:complexType>
                </xs:element>
            </xs:sequence>
        </xs:complexType>
    </xs:element>
</xs:schema>

The inferred schema is the most restrictive it can be, based on the XML used to infer it. The Create Schema command can also be used to generate an XSD Schema from the DTD or the XDR that are associated with the XML file being edited.

The user can also choose to create the schema manually. In that case, the user can still use the XML editor with all its capabilities to manually create the schema. The user will get the context-sensitive dropdown lists from which to select, all the syntax error reporting, and so on.

Attaching an XML Schema to an XML Document

Consider another scenario: The user already has the schema and an XML file, and now needs to figure out how to associate the two. There is an added constraint: the original XML file cannot be changed. Assuming that the XML document has all the right namespaces declared, the user can click on the file selector button on the Schemas property in the document properties window. (figure 6).

Figure 6. Document properties window

This command launches the following dialog:

Figure 7. XSD Schemas dialog

In this dialog, users can select all the schemas they want for validating the XML document. A schema can also be added to this list by selecting the Add button.

The Miscellaneous section of XML editor options (under the Tools->Option menu item) contains the location for the schema cache directory. When the XML editor is launched, it will compile, and keep available for future use, any schemas that are in this directory. The XSD Schemas dialog mentioned above is populated with the schemas in this directory.

If the XML file is part of a project that has schema files as well, the schemas in the project are also automatically included in the XSD Schemas dialog.

The schema cache directory also contains a Schema Catalog file. Below is an example of what the Schema Catalog file might contain.

Schema Catalog file

<SchemaCatalog xmlns="https://schemas.microsoft.com/xsd/catalog">
  <Schema 
   href="%VsInstallDir%/IDE/Policy/Schemas/TDLSchema.xsd" 
   targetNamespace="https://www.microsoft.com/schema/EnterpriseTemplates/TDLSchema"/>          
  <Schema 
   href="%VsInstallDir%/enterpriseframeworks/schemas/projectschema.xsd"
   targetNamespace="http://tempuri.org/ProjectSchema1.xsd"/>
  <Schema 
   href="%VsInstallDir%/packages/SDM/Schema/SchemaDefinitionModel.xsd"
   targetNamespace="https://schemas.microsoft.com/SchemaDefinitionModel/2003/10"/>
</SchemaCatalog>

The catalog file mitigates the scaling issue that you are bound to encounter if the number of interesting XSD files is very large. Saving all these XSD files in the Schema Cache directory will get very tedious, and is not conducive for organizing your work. The XML Editor will use the information in the Schema Catalog file to fetch the referred schemas and add them to the XSD Schemas dialog. A schema for the catalog file is already included in the Default Schemas directory.

Editing XSLT

When editing XSLT, feedback on XSLT errors in addition to the standard XML syntax errors is provided. For example, if a template element is specified without a match or name attribute, the template keyword is underlined with the red squigglies and the Error List is populated with this error.

The Intellisense dropdown selection list is filled with context-sensitive information. For example, if the user is editing the template element, the dropdown list contains the list of valid attributes. The list is also sensitive to what attributes have already been specified in the element. If the match attribute is already specified, the next time the list is shown match is not one of the options.

Figure 8. The context-sensitive Intellisense for XSLT

The Intellisense list is also sensitive to the namespaces that are being used. If the user starts with <, the dropdown list contains all the namespaces in scope (figure 9 below). As the user continues and types in <xsl:, the dropdown list changes to show only the valid element names from the namespace with prefix equal to xsl (figure 10 below). This context-sensitivity is available for all namespaces, and is not limited to the editing of the XSLT file.

Figure 9. Dropdown list before specifying the "xsl" prefix

Figure 10. Dropdown list after specifying the "xsl" prefix

Debugging XSLT Files

The XSLT debugger can be invoked in two ways: from the XML Editor itself, or from a CLR language program that uses an XSLTCommand object from System.XML.

For the first case, users will need to take the following steps to debug their XST:

  • Open the XSLT file in Visual Studio 2005 (it will be loaded in the XML Editor).
  • In the Document Properties for the XSLT document, specify the value of the Input property. This should be set to the XML data file that will be used for the transformation.
  • Specify a value for the Output property on the XSLT document. This should be the name of a file. This file will contain the results of the transformation. This is an optional step. If this value is not set, the XSLT Debugger will guess a value for it.
  • Set breakpoints on desired lines of the XSLT document.
  • Issue the Debug XSL command from the XML menu (or the XML toolbar).

Below is a picture of an in-progress XSLT debug session. After following the above steps, users will find themselves on a similar screen.

Click here for larger image.

Figure 11. Debugging XSLT in Visual Studio 2005

In the above screenshot of my example, I have used an XSLT file called "simple.xslt." This is the document on the left-hand side. The output file is called "simpleoutput.xml," and is on the right-hand side. The bottom of the picture shows the Locals, Watch and Call Stack windows. I will talk more about these in a little bit.

The other scenario in which debugging into XSLT becomes important is when XML is being transformed in a program. I am going to use C# as my example language here, but the information presented here applies equally to any other .NET language.

Example code for stepping into XSLT from C#

   public void DebugXSLT()
   {
            XsltCommand xsltcmd = new XsltCommand();
            xsltcmd.EnableDebug = true;
            xsltcmd.Compile(XSLTFile);
            XmlUrlResolver resolver = new XmlUrlResolver();
            XmlWriter writer = XmlWriter.Create(OutputFile);
            xsltcmd.Execute(XMLFile, resolver,null,writer);
     }

The above code compiles the XSLT with the EnableDebug flag set to true. This causes the IL generated by the XsltCommand object to have extra debug information. Stepping in from the xsltcmd.Execute(... statement will cause the code to step into the XSLT file. For more details on the actual API used in this example, please refer to Mark Fussell's March 2004 article.

The Debugging Windows

The Locals window displays any local or global variables defined in the style sheet. In figure 12 below, the CustomerName is a local variable that is in my sample style sheet. The other 4 variables are directly tied to the context information available at any given execution point in the style sheet.

Figure 12. Locals Window

Explanation of the context variables is in the table below:

Variable Name Description
$Current The value of the current context.
$Namespace Contains all the current namespaces in scope. This can be used by a debugger to resolve namespace prefixes that will be part of the variable names.
$Last The size of the context.
$Position Position of $Current in the context.

The Call Stack window lists the templates that are currently on the stack. Double-clicking on different items in the Call Stack window can be used to navigate the stack frame.

Figure 13. Call Stack Window

Conclusion

From the development-environment point of view, editing XML and debugging XSLT are two of the biggest pains for developers who develop applications that touch XML. In this article, I have provided an overview of the XML Editing and the XSLT debugging functionality in Visual Studio 2005 Beta 1.

I hope that this has been useful, and will spur some comments and feedback on the tools.