XmlTransform and SQL Documentation
XmlTransform's options are the key to controlling its output. Because there are so many options, it's best to use an options file
(as in the three examples near the end of the previous section) rather than typing options directly on the command line. The sample project includes XmlTransform_params.dat
for this purpose. To actually process your files, use a command similar to this:
> cd sqlDocProject\code
> java com.cleancode.xml.XmlTransform @XmlTransform_params.dat
character preceding the option file name tells XmlTransform to treat the options in the file just as if they were typed on the command line itself.
To set up the options file, then, you need to determine which options you need by answering the following set of questions:
- What operation(s) do you want to perform? You may elect to validate the input files, validate the output files, perform a transformation from source to target, or generate contents files.
Where are your source files? (This should be an absolute path to the root of your source XML directory tree.)
Where do you want to store the output HTML files? (This should be an absolute path to the root of your target directory tree.)
What supplemental parameters have you defined in your XSLT file for which you need to supply values? The sample XSLT file translate.xsl defines three common parameters: a revision date (revdate), a copyright date (copyright), and a release version (relVersion). Having these parameters in the XSLT mapping means that if and when you need to change any of those, you change it in the XSLT file, rerun XmlTransform, and it updates every file in your hierarchy. The xslParmList option is a simple, comma-separated list of items.
If you elect to generate contents (index) pages, do you want the contents page for each directory within the directory or elevated to its parent? Suppose you have a folder /source/abc that contains a contents template file /source/abc/_index.xml. This template file is unusual in several respects. It must be named "_index.xml"; there must be one such file per directory; and it actually goes through an extra step of translation, from a "precursor" XML file to a regular XML file, i.e. the contents page (still in XML, so still considered a source file). You can elect to place this generated contents page in the parent folder, which causes the contents file to assume the name of the folder. That allows you to have several subdirectories that elevate their contents to a common parent without contention. That is, the index page (/source/abc/_index.xml) maps to /source/abc.xml (and eventually to /target/abc.html). If you instead choose to place contents pages in the same directory as the set of files to which they link, then all the contents pages will be named "index.xml." In that case, /source/abc/_index.xml would map to /source/abc/index.xml and ultimately to /target/abc/index.html. Elevating contents to the parent directory fits more naturally to a hierarchical model where you want to navigate up, down, and sideways in a web site. Putting index/content pages in the same directory, however, is a widely used convention, so XmlTransform provides the option to choose whichever you prefer.
If you elected to generate contents pages, where do you want the contents inserted in your template? The precursor contents page contains XML with a special placeholder specifying where to insert the dynamically generated contents list. You can select an arbitrary XML element as a placeholder for the relevant group of files. That element—with no children and possibly one attribute (see next question)—controls where XmlTransform inserts summary information for the relevant group of files.
If you selected to generate contents pages, and you wish to subdivide the files into more than one group, where is the group identifier in each file? In the simplest case, you need only provide a single <cc:files> element to list all files in one section in the contents page. You may include a group attribute and set its value to an empty string. However, by specifying a non-empty value for the group attribute you may subdivide the files into smaller groups. For SQL documentation, one natural group separation is between stored procedures and functions. In the contents template you specify a group attribute on the placeholder element for each group you wish to use. Here is a portion of the _index.xml file for the SQL documentation set:
You also need to instrument each source file to identify what group it belongs to. Stored procedure files should use, for example, <cc:group>sp</cc:group>
while function files should use <cc:group>fn</cc:group>
. These values are not fixed; you may use different values if you prefer as long as they match the group attribute of the cc:files
elements (shown above).
You specify the name and location of these XML nodes with the groupIdXpath
option. This example of a generated intermediate file (index.xml
) shows how the template (_index.xml
) is filled out with the appropriately tagged elements:
Observe how the list of three files has been split between the two groups based on the directives in each file that match the group
attributes specified in the contents template file.
|Figure 4. Generating Groups on a Contents Page: Here are the main steps involved in the group generation process.|
clarifies this process. Look for the <cc:group>
elements in the representative set of source files (1). Those groups are called out in the contents template (2). In its first pass, XmlTransform weaves them together, filling out each group in the contents template with information from the source files identifying themselves as a member of that group (3). Its second pass then takes the filled out contents file and runs it through an XSLT transformation (4), along with all the other "regular" source files. This converts your extended XHTML language into XHTML renderable by any browser (5).
If you elected to generate contents pages, where do you want to place the identification of the generated contents file? This is important because XmlTransform tries not to inadvertently overwrite material that it did not generate in the first place. The first time you run XmlTransform there is no issue, as no intermediate contents files exist. For subsequent runs, the generated index.xml file will exist. To avoid overwriting a handcrafted file of the same name, it looks for the presence of a node specified by the generatorNode option.
How much information do you want XmlTransform to report, and where do you want it delivered? XmlTransform uses a flexible diagnostic logging system that allows you to review as much or as little output about the execution as you wish. First you specify values for the possible diagnostics; XmlTransform has six available, designated A through F. The most useful approach is to specify powers of two so that you may combine the diagnostics as you please by bitwise ORing. Additionally, there are a couple other diagnostics that provide some useful output, one to show version numbers for each loaded module, and one to show values of all program options.
// to show all module versions
// to show all configuration options
// to show program-specific details
After defining values for each diagnostic, you then set the run-time diagnostic level (VERSION_DIAG
) to a combination of these. A value of 10, for example, will activate diagnostics A and C (because 10 [1010 in binary] is the sum of the values for XMLTRANSFORM_C_DIAG [
1000 in binary] and XMLTRANSFORM_A_DIAG
[0010 in binary] ):
The final component for diagnostic setup is specifying where to deliver the output. You have four channels (stdout
, and webpage
) which may each be routed to two streams (standard output and standard error). Again, these are specified by enabling the appropriate bit combinations:
// send to log file (8) and stdout (1)
// send to log file (8) and stderr (2)
Run, XML, Run
|Author's Note: Complete details of the Diagnostic API used are available here.
After answering all the questions in the preceding section, collect the resulting options in your options file, and you're ready to execute XmlTransform:
> cd sqlDocProject\code
> java com.cleancode.xml.XmlTransform
Here's the diagnostic output for the SQL documentation generation:
Processing . (level=0)
XmlTransform.isGeneratedFile> scanning candidate contents:
DocumentPlus> VERSION DocumentPlus 9
[contents] processing index.xml:
one or more files newer than output file
Generating contents file (3 files):
Scanning contents template
Contents file complete:
XmlTransform.dirHasChanged> files added in
[XSL] processing index.html:
input file is newer than output file
Loading XSL for level 0: translate.xsl
XslQualifier> VERSION XslQualifier 9
converted @ Wed Oct 24 14:05:38 PDT 2007
[XSL] processing FN_list2table.html:
output file does not yet exist
converted @ Wed Oct 24 14:05:39 PDT 2007
[XSL] processing FN_list2tableIndexed.html:
input file is newer than output file
converted @ Wed Oct 24 14:05:39 PDT 2007
[XSL] processing SP_map.html:
files added or deleted in current directory
converted @ Wed Oct 24 14:05:39
=== Summary ===
start time: Wed Oct 24 14:05:38 PDT 2007
end time : Wed Oct 24 14:05:39 PDT 2007
elapsed : 0.79 seconds
max depth reached: 0
dirs processed : 1
files processed : 4
files transformed: 4
failed transform : 0
files validated : 0
failed validation: 0
There are only three SQL files and one contents file in the sample project so the output is quite brief. The diagnostic level set above (0x00A
) provides the output shown. It includes an explanation for why each file is regenerated—I have highlighted these in bold. Try enabling different bits to see other available diagnostic output. You might, for instance, want to enable the INPUTOPTIONS_DIAG
) to list all options used by the program, including both the ones you set and the default values for those you did not. Adding it to the current DIAG_LEVEL
. The XmlTransform API
provides details on what each of the A through F diagnostics report on, as well as describing the complete set of XmlTransform options.
After generating your documentation set, you need only install it on your web server. When code changes inevitably come along, you can then quickly and easily regenerate an up-to-date documentation set with just a couple of simple commands.