.Net Configuration Section Documentation Generator

The .Net Configuration Section Documentation Generator lets you generate schemas and documentation for configuration sections used in .Net’s configuration system (e.g. app.config or web.config files), which are defined by a class that derives from the System.Configuration.ConfigurationSection class.

The documentation generator is a command-line tool that operates in two modes. The reflect mode uses reflection to inspect the properties of a class that derives from the ConfigurationSection class, and generates an XML schema file (XSD) for the section and all its child elements. The document mode generates an HTML documentation file based on a schema created with the reflect mode.

If you have any feedback, please leave a comment here.

Reflect mode

To use the documentation generator in reflect mode, launch it with ConfigurationDocumentationGenerator.exe reflect. The command line arguments specify the assembly file containing the configuration section, the type that defines the configuration section, the name of the root element for the section, and the output file name for the schema. If you invoke the reflect mode without arguments, a full overview of the possible command line arguments is given.

The reflect mode will load the specified assembly file, and search for the specified type inheriting from ConfigurationSection. It will generate a schema and save it in the specified output file. If the output file already exists, the existing schema will be updated, leaving any annotations already added intact.

Reflection generates a schema as follows:

  • For every ConfigurationElement type found by recursively searching the configuration properties (and including the ConfigurationSection itself) it will create an xs:complexType element to describe the configuration element.
  • For every property of a ConfigurationElement that has the ConfigurationPropertyAttribute applied, it will generate an xs:element in the complex type if the property’s type derives from ConfigurationElement, or an xs:attribute if it does not. These elements are grouped using xs:all.
  • For types derived from ConfigurationElementCollection, it will add child xs:elements for the add, remove and clear elements (or only add if the collection type is a basic map). These are grouped using xs:choice with maxOccurs="unbounded".
    • A separate complex type is generated for the remove elements that contains only the collection key of the item type.
  • For property types that do not derive from ConfigurationElement, these types are mapped to a simple type. If the CLR type doesn’t map to a pre-defined simple type, a new xs:simpleType is created for them. For enumerations, this is populated with a suitable restriction based on the enumeration’s values. Otherwise, the simple type is left empty so you can manually define it.

The reflect mode has the following limitations:

  • Since the element name of the element for the ConfigurationSection itself is not specified in code, it must be manually specified when invoking the documentation generator.
  • For types derived from ConfigurationElementCollection it is required to apply a ConfigurationCollectionAttribute to indicate the item type, collection type (basic map or add/remove/clear map), and the names of the add, remove and clear elements. In the case of a basic map, you must also specify the element name using the ConfigurationCollectionAttribute.AddItemName property.
    • For default collections, this attribute may be applied to the configuration property; otherwise, it must be applied to the type deriving from ConfigurationElementCollection itself.
  • If a configuration element collection also has other configuration properties which are elements, all elements will be grouped in an xs:choice with maxOccurs="unbounded". This is not correct, because it means the schema will allow all elements to be repeated many times, while in fact the configuration section will not load if they occur more than once. Unfortunately, it is not possible to accurately specify the real schema using XSD 1.0 in this case.

Document mode

To use the documentation generator in document mode, invoke it using ConfigurationDocumentationGenerator.exe document. It takes arguments to specify the XSD file and optionally the output file and XSL transform to use. Invoke it without arguments to view a description of all the arguments.

The document mode will read the XSD file, and run the indicated XSL transform to generate an output HTML file. In this mode the documentation generator is basically just an XSLT processor, and is therefore not limited to XSD schemas generated by the reflect mode. However, the included Default.xslt transform is geared towards schemas generated by the reflect mode, and does not support all XSD features. It is possible to customize the Default.xslt file, or specify a custom XSL transform.

The default XSL transform will create a section for every element in the file that can be reached from the top-level xs:element tag. Note it creates a section for every element, even if multiple elements use the same complex type. These sections list the syntax, attributes and child elements of the elements.

In addition, the default transform also adds a section for every top-level simple type in the file. For enumerations, the possible values are listed.

In order to add documentation to an XSD file, add xs:annotation/xs:documentation elements to it. The content of these elements will be included in the HTML documentation by the default XSL transform. You can add documentation to xs:schema, xs:element, xs:attribute, xs:simpleType and xs:enumeration elements. When updating a schema with the reflect command later, these annotation elements will not be removed. The documentation may contain HTML elements in the XHTML namespace.

You can use a few attributes specified to the documentation generator in your schema. These attributes are in the xmlns:doc="http://www.ookii.org/documentation" namespace. Apply the doc:title attribute to the xs:schema element to specify the title of the documentation file. Use the doc:ref and doc:refName attributes on an xs:element to have the documentation for that element link to another element, rather than actually outputting the documentation for that element. This is useful if the element uses the same complex type as another element and you want to avoid repeating the same documentation. The doc:ref attribute should use the full path to the element, with element names separated by underscores, while the doc:refName attribute specifies the link text. For example, to link to the documentation of someElement which is a child of someSection, using doc:ref="someSection_someElement" doc:refName="someElement".

If the XSD contains a cycle (a complex type has a descendent element whose type is that same complex type; this can happen in a configuration section if it has a configuration element with a descendent property of that same type), this is detected by the default XSL transform, but all it does is output a warning message in the HTML and prevent infinite recursion from crashing the documentation generator. To handle cycles, have the descendent element use doc:ref and doc:refName to refer back to its ancestor of the same type. This stops recursion and avoids the warning message.

Customizing the behavior of the documentation generator

You can customize the simple type mapping for the reflect mode, and the XSL transform for the document mode.

How the reflect mode maps a CLR type to an XSD simple type is defined in the ConfigurationDocumentationGenerator.exe.config file. The schema for this configuration is explained in the documentation generator configuration documentation.

You can customize the XSL transform by editing the Default.xslt file, or by specifying an alternative XSLT file on the command line. It’s usually recommended to make a copy of the Default.xslt file if you want to customize it. For example, you can tweak the generated HTML or the included CSS to alter the appearance of the documentation.