10

 

XML Documentation

 

XML is used extensively to document program code. Apart from its status of a mere acronym for eXtensible Markup Language, XML has a bounden duty to achieve miracles. However, in this chapter, we would be utilizing XML for the temporal task of documenting our code.

 

a.cs

class zzz

{

public static void Main() {

}

}

 

Run the compiler as 

 

>csc a.cs /doc:a.xml

 

a.xml

<?xml version="1.0"?>

<doc>

    <assembly>

        <name>a</name>

    </assembly>

    <members>

    </members>

</doc>

 

This is the smallest possible XML file that can be effectively generated by the compiler. The compiler with the /doc option, followed by a colon and filename, creates the XML file, which documents the C# program.

 

Anything placed within the <> brackets is called a tag. At the expense of sounding tediously repetitive, we once again reiterate that, each and every XML file must necessarily start with a tag beginning with <?xml>. This has to be followed by an attribute called version. Presently, the only permissible value that can be assigned to version is 1.0. There may never be a version 1.1 or 2.0.

 

Subsequent to this, a root tag called 'doc' is specified, which envelopes all other tags within the file. We have a tag called 'assembly' which owns another tag called 'name' that encloses our assembly name 'a'. The name of our program file is 'a'. There are no members to be documented, therefore, no names are noticeable within the member tags. This is the basic structure of our XML file.

 

It is the bare minimum, no frills structure, created by the compiler. Now, let us refurbish and garnish it through our own contribution.

 

a.cs

class zzz

{

/// <vijay>

public static void Main()

{

}

}

 

We have added an XML tag in the .cs file. The documentation clearly states that an XML tag in a .cs file cannot begin with two slashes, since they are reserved for comments. It should instead have three slashes. The use of the two slashes generates the following warning:

 

 

Output

a.cs(4,3): warning CS1570: XML comment on 'zzz.Main()' has badly formed XML -- 'End tag 'member' does not match the start tag 'vijay'.'    

 

From now on, we shall only display the pertinent portions of the XML file, while ignoring the portion that is invariant, such as, the doc and the /doc tags. So in the file created as:

 

a.xml

<?xml version="1.0"?>

<doc>

    <assembly>

        <name>a</name>

    </assembly>

    <members>

        <!-- Badly formed XML comment ignored for member "M:zzz.Main" -->

    </members>

</doc>

 

we will display only 

 

xml fragment:

    <members>

        <!-- Badly formed XML comment ignored for member "M:zzz.Main" -->

    </members>

 

In the next program, a closing tag of 'vijay' is specified.

 

a.cs

class zzz

{

/// <vijay>

/// Function Main gets called first

/// </vijay>

public static void Main()

{

}

}

 

xml

<members>

   <member name="M:zzz.Main">

        <vijay>

        Function Main gets called first

        </vijay>

    </member>

</members>

 

The earlier program generated an error, since there was no corresponding end tag to the tag 'vijay'.

 

Every tag in XML must necessarily have a start tag and an end tag. We are at liberty to choose any name for the tag. Therefore, we have chosen the name 'vijay'.

 

The compiler creates a tag called 'member' under the tag members, and adds an attribute called 'name'. This attribute is initialized to the name of the C# entity, which is the position where the tag is placed. The value assigned to name is, as follows:

     The letter M,

     Followed by a colon separator,

     Followed by the name of the class zzz,

     Followed by a dot separator

     Finally, followed by the name of the function i.e. Main.

 

Thus, it displays M:zzz.Main.

 

The tag 'vijay' and the text enclosed between the start and end tags of 'vijay' subsequently, get enclosed within the members tag.

 

a.cs

/// <mukhi>

/// Our first class

/// </mukhi>

class zzz

{

/// <vijay>

/// Function Main gets called first

/// </vijay>

public static void Main()

{

}

}

 

xml

<members>

        <member name="T:zzz">

            <mukhi>

            Our first class

            </mukhi>

        </member>

        <member name="M:zzz.Main">

            <vijay>

            Function Main gets called first

            </vijay>

        </member>

</members>

 

Now, we have added a tag called 'mukhi' to the class. It is however, not added to the function. So presently, there are two member tags, and each has been assigned a name within the members tag. The value assigned to the member name, which encloses 'mukhi' is, T:zzz. This is created in a manner akin to that of a function, with the exception of the prefix M, which has now been replaced by T.

 

The rationale behind introducing XML tags is that, a program known as an XML Parser can interpret the above XML file, and subsequently, create legible output. But, the prime impediment that we have to confront and surmount is, the reluctance of programmers to document code in the first place.

 

a.cs

class zzz

{

/// <mukhi>

/// Our Instance Variable

/// </mukhi>

public int i;

public static void Main()

{

/// <vijay>

/// Our first variable ii

/// </vijay>

int ii;

}

}

 

Output

a.cs(12,5): warning CS0168: The variable 'ii' is declared but never used

a.cs(9,1): warning CS1587: XML comment is not placed on a valid language element

a.cs(6,12): warning CS0649: Field 'zzz.i' is never assigned to, and will always have its default value 0

 

xml

<members>

        <member name="F:zzz.i">

            <mukhi>

            Our Instance Variable

            </mukhi>

        </member>

</members>

 

Oops! The tags that we give within a function have not been reflected in the XML file. The instance variable i is flagged with an F, but the local variable ii is not reflected in the XML file at all.

 

We have carried this out on purpose, with the intention of demonstrating that it is not permissible to write XML tags within functions. Even though our preceding action would not produce any error, the compiler shall, in any case, ignore our work of art.

 

We will now dwell upon the names or string ids, which the compiler generates for names of entities. They are as follows:

     N stands for a Namespace.

     T represents a type, class, interface, struct, enum and delegate.

     F denotes a field.

     P is indicative of either properties or indexers.

     M indicates all methods

     E represents an event.

     ! is indicative of an error. 

 

a.cs

/// <vijay>

/// Our first variable ii

/// </vijay>

namespace aaa

{

class zzz

{

public static void Main()

{

}

}

}

 

Output

a.cs(1,1): warning CS1587: XML comment is not placed on a valid language element

 

We do not enjoy the license to place tags wherever we desire. Thus, a warning is issued when a tag is placed on a namespace, although no error is generated. In the earlier case too, a similar warning was issued, when we had placed the tags in a function.

 

a.cs

class zzz

{

/// <vijay>

/// Our function <c>Main</c> is the starting point

/// </vijay>

public static void Main()

{

}

}

 

xml

<member name="M:zzz.Main">

            <vijay>

            Our function <c>Main</c> is the starting point

            </vijay>

</member>

 

If we place the tag <c> and </c> around some text in a tag, the tag gets copied verbatim, into the XML file. It is indicative of the fact that the text represents some code. To mark multiple lines of code, the code tag may be used instead. The example tag also works in a similar manner.

 

a.cs

/// <exception cref="System.Exception"> Our exception class </exception>

class zzz

{

public static void Main()

{

}

}

 

xml

<member name="T:zzz">

            <exception cref="T:System.Exception"> Our exception class </exception>

</member>

 

The exception tag works as demonstrated above, with a single difference in that, the attribute cref is inspected for accuracy. This attribute should represent a valid C# entity, otherwise, the following warning is displayed:  

 

 /// <exception cref="System.Exceptions"> Our exception class </exception>

 

Output

a.cs(2,22): warning CS1574: XML comment on 'zzz' has cref attribute 'System.Exceptions' that could not be found.

 

xml

<member name="T:zzz">

            <exception cref="!:System.Exceptions"> Our exception class </exception>

</member>

 

All the tags expounded by us so far, have a similar functionality. This surely must have kindled your curiosity to discover the rationale behind employing so many tags.

 

This is so, because each of these tags, documents different features of the language. Let us assume that we yearn for a bulleted list in our final documentation. We would have to use the following tags to accomplish it:

 

a.cs

/// <list type="bullet">

/// <item>

/// <description>One</description>

/// </item>

/// <item>

/// <description>Two</description>

/// </item>

/// </list>

class zzz

{

public static void Main() {

}

}

 

xml fragment

<member name="T:zzz">

            <list type="bullet">

            <item>

            <description>One</description>

            </item>

            <item>

            <description>Two</description>

            </item>

            </list>

 </member>

 

The attribute type can also be assigned the values of bullet, number or table.

Bear in mind, that an external program will interpret the XML tags. Thus, the designers of the language standardized tags for describing different things. If the same tag had been utilized for documenting every feature, a single program would have sufficed to document the entire C# code. We have employed tags such as 'vijay' and 'mukhi' to document our classes. Chaos would reign supreme, if everyone decided to use his or her own names. Appended below is a brief summary of the various tags that can be employed in the XML file:

     The param tag is used to document the parameters to a function.

     The paramref tag is used to document a parameter name.

     The permission tag is used to document the access allowed to a member.

     The remarks tag is used to specify the overall information for a class.

     The return tag has been introduced to document the return values of functions.

     The seealso tag helps in implementing the 'see also' section at the bottom of help sections.

     The summary tag documents all members of a type.

     The value tag documents all the properties.