Monday, November 2, 2009

Hack 32. Enable IntelliSense for HTML and XML Documents











 < Day Day Up > 





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.







Figure 4-22. IntelliSense for attributes with enumerations defined







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>









Figure 4-23. An appSettings node with IntelliSense schema applied











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.







Figure 4-24. Adding a tag with the defined alias







Visual Studio will now display your types in the list of available

tags and will provide IntelliSense for the defined

attributes.





Ben Von Handorf





















     < Day Day Up > 



    No comments: