Getting Started
Enable IntelliSense in Your Documents
Use the new XML editor features to enable IntelliSense in your XML documents.
Technology Toolbox: Visual Studio 2005, Visual Studio 2003, XML 1.0 and Namespaces
Visual Studio has provided an XML editor that offers IntelliSense for any given XML schema since Visual Studio 2003. Microsoft upgraded this XML editor in Visual Studio 2005.
In VS 2003, IntelliSense works if the namespace declaration URI (Uniform Resource Identifier) matches one of the schemas in your local VS folder. This has always worked well and continues to work in VS 2005, but it's actually the wrong approach to validate XML schemas.
I'll cover the limitations of the VS 2003 approach for providing IntelliSense in your XML documents, including why you shouldn't use namespace URIs for schema validation. I will also cover a better approach, using the XML-Schema Instance (XSI) namespace and how you can use it to solve the problems presented by the original implementation. Finally, I will show you how to create an example that leverages the new XML editor in VS 2005, using the XSI namespace to perform validation and provide IntelliSense against any locally or remotely hosted XML schemas.
There are many reasons why you might want to edit XML documents in Visual Studio. For example, you might want to use it to edit a Web.Config file, an XSL Transformation (XSLT), or any XML input/configuration files for your own custom applications. To enable XML IntelliSense in Visual Studio 2003, locate your schema, then copy it to C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\Packages\schemas\xml. Next, open a new XML document, and reference the schema by its namespace URI in the root element.
By default, VS 2003 provides a File/New XSLT template, but doesn't include the schema. You can download the freely available schema from Fesersoft (See Additional Resources). By copying the schema to the location mentioned above, you will start to get IntelliSense. Updating the File/New xsltfile.xslt template is optional. It is located in C:\Program Files\Microsoft Visual Studio .NET 2003\Common7\IDE\NewFileItems.
This has been a good solution for providing IntelliSense for XML documents, and my own company has been using it for more than two years. It's effective, but has a couple weaknesses.
The first is basically an inconvenience; the schemas must reside locally. This creates a problem when XML schemas need to be distributed to a team of developers, especially if the schemas are evolving and/or are not centrally located. You can overcome this problem by scripting Visual Studio's OnStartupComplete event to download the schemas from multiple locations to the local drive.
The second problem with this technique relates to a fundamental XML issue that occurs when you use XML namespace URIs to locate schemas for validation and IntelliSense. The purpose of XML namespaces is for qualifying elements and attributes, similar to how people qualify a first name with a last name. The syntax of a namespace declaration is xmlns:prefix="anyURI" where you can express the URI as either a Uniform Resource Locator (URL) or a Uniform Resource Name (URN). In other words, you can write a namespace URI as either http://www.foo.com or urn:www-foo-com.
What's in a Name(space)?
It is mere coincidence that many namespace URIs look like valid URLs. In fact, if you navigate to XSLT's namespace declaration URL (http://www.w3.org/1999/XSL/Transform), you'll get a schema that reads: "Someday a schema for XSL Transformations will live here." A namespace URI is nothing more than a label, and technically, it provides no information about the location of the corresponding schema. This explains why the schema files must reside locally in VS 2003. There is no other way to locate them.
The problem remains: You need a way to associate an XML document's namespace URIs to their schema locations. You might be aware that the XML-Schema Instance (XSI) namespace is used to define types, such as xsi:type="integer." One of the more powerful and lesser known uses of this namespace is its ability to associate XML schemas.
Let's examine the name of the XML-Schema Instance namespace. In object-oriented programming, you have classes and objects that represent the static compile time and dynamic runtime parts of an application. Objects are running instances of classes. XML behaves similarly; a schema document is like a class. When you create a new XML document that uses a schema, it's like creating an object instance of a class. This new XML document is an instance document. The name "XML-Schema Instance" implies that there is a separation of a schema and its instance. It also implies that you will use the schema within an instance document.
Conversely, namespace declarations can be used in both schema documents and instance documents. Namespace declarations provide uniquely named labels, but the XSI namespace provides the ability to associate an instance document with its schema(s) and to reference the schema's types (see Table 1).
The XSI namespace has two attributes for associating schemas: xsi:noNamespaceSchemaLocation and xsi:schemaLocation. You can use xsi:noNamespaceSchemaLocation to reference your schema if the schema does not define a target namespace:
<foo xmlns:xsi="?"
xsi:noNamespaceSchemaLocation=
"http://www.foo.com/foo.xsd"
>
If your instance document defines schemas that have target namespaces, use xsi:schemaLocation to associate them. The syntax is a white-space delimited list of namespace URI and schema URL pairs:
<foo xmlns:xsi="?"
xmlns:a="urn:a"
xmlns:b="urn:b"
xsi:schemaLocation="
urn:a http://www.foo.com/a.xsd
urn:b http://www.foo.com/b.xsd"
>
The VS 2005 XML editor (or any "smart" XML processor) can use these XSI attribute definitions to download the schema for validation or IntelliSense purposes.
IntelliSense in the Document
The next step is to put it all together. Consider the XSLT example discussed previously. VS 2005 ships with a File/New xsltfile.xslt template, but there is no corresponding schema file. To verify, you can double check the list of schemas located at C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas, or call up an XSLT document and see if the IntelliSense works or not. (I have used both the Beta and the free version from the VS 2005 launch event, and neither works.) The XML editor in VS 2005 has been rewritten from scratch to be fully XML compliant. This means full support for schema-based validation and neat UI features such as document outlining.
Another key new feature: added support for the XSI namespace. The improved (and stricter) XML editor means that the popular earlier schema provided from Fesersoft no longer works. You can find a new working schema in the online code for this article (see the Go Online box for details). Also, you can see this schema in action by visiting this URL: http://www.vergentsoftware.com/downloads/xslt.xsd.
Begin by modifying the File/New xsltfile.xslt template to use the XSI namespace to reference this schema. Open the File/New xsltfile.xslt template located at C:\Program Files\Microsoft Visual Studio 8\Common7\IDE\NewFileItems, then add the XSI namespace declaration (see Figure 1).
Once you define the XSI namespace, the editor provides the IntelliSense for the xsi:schemaLocation attribute. Now use the xsi:schemaLocation attribute to point the XSL namespace to the schema that you've set up on your own Web server, or point to the one hosted at www.vergentsoftware.com. Finally, save and close the File/New xsltfile.xslt template:
xsi:schemaLocation="
http://www.w3.org/1999/XSL/Transform
http://www.vergentsoftware.com/downloads/xslt.xsd"
You can test this code by creating a new XSLT instance document from the File/New menu. Note that the XML editor downloads the schema automatically and uses it to provide both validation and IntelliSense (see Figure 2).
The support for xsi:schemaLocation and xsi:noNamespaceSchemaLocation in VS 2005 are compatible with any valid path. This means you can use relative paths to reference schemas within your project, or UNC paths to reference schemas on other machines. You can also experiment by hosting the schema discussed in this article on your own Web server and updating the xsi:schemaLocation attribute appropriately.
About the Author
William Wen is a senior software engineer for InfoSpace, Inc., where he customizes and uses Visual Studio to write Web applications using an XSLT-like scripting language. If you have used www.dogpile.com on the Web, or personalized data services on a cell phone through your carrier, you''ve probably used Wil's code. Wil enjoys working with XML technologies and can be reached at [email protected].