Hack 32. Enable IntelliSense for HTML and XML Documents
Eliminate errors in XML and HTML editing by
adding IntelliSense support for your configuration sections and
controls.
Visual Studio provides developers with IntelliSense in code by
interrogating compiled objects or assemblies, but it is unable to
provide the same assistance when editing XML, HTML, or ASPX files. In
this hack, you will learn how to enable IntelliSense in these
documents using an XML schema.
IntelliSense in HTML and XML documents relies on XML schema. ASP.NET
has schemas defined for the built-in types (DataGrid, TextBox, etc.),
but if you find yourself editing custom sections in application
configuration files or want to add IntelliSense to your custom
controls, you can create your own schema and reference it from your
files. Visual Studio will then add the elements you define in your
schema to the default ones and provide you with the same level of
support you expect from the built-in controls.
4.10.1. Basic Structure of an IntelliSense Schema
The schema you need to create is composed
of three basic sections: the header, the names, and the types.
4.10.1.1 Header
The schema header is fairly standard and will
look almost identical for each schema you create:
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema
targetNamespace="http://www.orbitalspacelaser.com/schemas"
xmlns="http://www.orbitalspacelaser.com/schemas"
elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vs=
"http://schemas.microsoft.com/Visual-Studio-Intellisense"
vs:friendlyname="Custom Intellisense Forms Controls"
vs:ishtmlschema="false"
vs:iscasesensitive="false"
vs:requireattributequotes="true">
The sections that you will need to change are the
targetNamespace, the xmlns, and
the vs:friendlyname attribute. Generally,
targetNamespace and xmlns
should be the same and set to some unique schema namespace. The
format is a URL that uniquely identifies the namespace that this
schema describes. A format such as
http://OrganizationName/schema/ProjectName is
generally acceptable.
The vs:friendlyname attribute should be set to
some string that succinctly describes the set of items you are
providing for IntelliSense with this schema.
Note that the schema must have a matching close tag
(</xsd:schema>) at the end of the document
for it to be validated and used.
4.10.1.2 Names
Following the header section are the names of the
items that are valid in the schema. This section is basically a
simple list of items that are valid in the document you will be
editing, be it a list of custom control names that are valid in an
ASPX or elements that are valid in a XML configuration file:
<xsd:element name="AlphaControl" type="AlphaControlDef" />
The name attribute will determine what Visual
Studio matches in the file. Thus, the preceding element will match
<AlphaControl> in the XML file you are
editing (remember that ASPX files are XML files). The
type of the element will be defined in the next
section. For most situations, using the name and adding
"Def" to the end should be
sufficient.
4.10.1.3 Types
The types defined in the schema are
actually what Visual Studio will use to create the IntelliSense
prompts when you are editing a file. Types can be very complex and
can also be nested, so if you have a hierarchy (with custom controls,
for example) you can mirror that in the schema:
<xsd:complexType name="AlphaControlDef">
<xsd:attribute name="Alpha" type="xsd:boolean" />
<xsd:attribute name="Delta" type="xsd:double" />
<xsd:attribute name="Gamma">
<xsd:simpleType>
<xsd:restriction base="xsd:string">
<xsd:enumeration value="ValueOne" />
<xsd:enumeration value="ValueTwo" />
<xsd:enumeration value="ValueThree" />
</xsd:restriction>
</xsd:simpleType>
</xsd:attribute>
<xsd:attributeGroup ref="BaseClassAttributes" />
</xsd:complexType>
This type represents a few simple attributes that demonstrate much of
the flexibility of the schema. Our element contains three attributes
and also a group of attributes defined elsewhere. Both Alpha and
Delta have simple xsd types set, and Visual Studio
will simply prompt you to enter a value of the appropriate type,
providing a list of choices where applicable (such as True/False with
Boolean attributes).
The attribute definition for Gamma defines a custom
simpleType, which allows us to enhance the
built-in xsd types. We start with a string, but we
add a restriction to it. When we edit this type in Visual Studio,
this restriction tells Visual Studio that the value for Gamma can
only be one of the options listed in the enumeration, so it will
prompt the developer to pick one of them, as shown in Figure 4-22.
XML schemas provide a great many options on how to build these
attributes, but these simple options should cover most controls and
configuration sections you will need to create.
4.10.2. Considerations for Application Configuration Files
Application configuration files are
straight XML and will generally be custom to an application, so
creating the schema is a fairly straightforward process. In general,
your use of attribute groups and other more complex constructs will
be limited in these situations.
4.10.3. Considerations for Custom Controls
Creating schema for a custom
control often involves
extending the existing schema of one of ASP.NET's
built-in controls. In this situation, we can eliminate a lot of
typing and create a more useful schema by copying the appropriate
portions of the default
ASP.NET schema.
After creating your schema file, locate and open the file
<VS Install
Directory>\Common7\Packages\schemas\xml\asp.xsd. This file contains the schema for all the
built-in controls. Find and copy into your new schema the appropriate
attributeGroup elements that apply to your control.
|
Editing the asp.xsd is a bad idea. Not only are
you potentially breaking IntelliSense for the built-in controls, but
the next time you upgrade or patch Visual Studio, your changes will
probably be lost.
|
|
In most cases, you will be able to use the
ControlAttributes group even if no other groups apply.
After pasting these definitions into your schema, you can simply
reference them with an attribute group tag inside the appropriate
type:
<xsd:attributeGroup ref="ControlAttributes" />
After that, your type will automatically provide all the attributes
defined in the referenced attribute group.
4.10.4. Installing the Schema
After you have created the schema, you need
to place it where Visual Studio expects to find it. The normal
directory will be <VS Install
Directory>\Common7\Packages\schemas\xml. After you copy
your new schema to this directory, Visual Studio will be able to
reference it in files in which the appropriate XML namespace is
imported. Be sure to restart your Visual Studio environment to ensure
the new schema is recognized.
4.10.5. Referencing the Schema
Referencing
a schema after it has been installed is
a matter of adding an attribute to the document you are editing to
make Visual Studio use the XML namespace you created. To do this,
simply add an xmlns attribute to the root element
in the file with a value equal to the
targetNamespace you defined in your schema.
4.10.5.1 Application configuration files
It's easy to set configuration files to use a
schema. Simply add the xmlns to the node below
which your schema should apply. For example, if your schema defines
the elements your application would expect in the
appSettings node of the file, the types and
attributes you had defined in your schema would apply beneath that
point, such as with this schema, which provides assistance adding a
ConnectionString attribute to your
appSettings (Figure 4-23 shows it
in action):
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema
targetNamespace=
"http://www.orbitalspacelaser.com/schemas/config"
xmlns="http://www.orbitalspacelaser.com/schemas/config"
elementFormDefault="qualified"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:vs=
"http://schemas.microsoft.com/Visual-Studio-Intellisense"
vs:friendlyname="Custom Intellisense Forms Controls"
vs:ishtmlschema="false"
vs:iscasesensitive="false"
vs:requireattributequotes="true">
<xsd:element name="ConnectionString" type="ConnectionStringDef"/>
<xsd:complexType name="ConnectionStringDef">
<xsd:attribute name="Server" type="xsd:string"/>
<xsd:attribute name="Database" type="xsd:string"/>
<xsd:attribute name="User" type="xsd:string"/>
<xsd:attribute name="Password" type="xsd:string"/>
</xsd:complexType>
</xsd:schema>
|
Unfortunately, if you apply a schema to one of the default
configuration sections (system.web in a
web.config for example), .NET will be unable to
parse the configuration file. If IntelliSense is required on a
default node, you can add the xmlns attribute, but
you must remove it before running the
application or the parsing of the configuration file will fail.
|
|
4.10.5.2 ASPX files
For an ASPX file, this means changing the body
tag to include the namespace and giving it an alias:
<body xmlns:cc1="http://www.orbitalspacelaser.com/schemas/controls">
The cc1 will then be the alias for this namespace.
If you are referencing a custom control library, it should match the
TagPrefix defined in the Register directive at the top of the page:
<%@ Register TagPrefix="cc1"
Namespace="CustomControlIntellisense"
Assembly="CustomControlIntellisense" %>
Now when you wish to reference the control, simply open a tag with
the alias defined, as shown in Figure 4-24.
Visual Studio will now display your types in the list of available
tags and will provide IntelliSense for the defined
attributes.
�Ben Von Handorf
|
No comments:
Post a Comment