Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Add Custom XML Documentation Capability To Your SQL Code : Page 7

By adding XML-based documentation capability to your SQL code, you can automatically extract and format tagged comments into a complete API documentation set for your SQL libraries.




Application Security Testing: An Integral Part of DevOps

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

The @ 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.
  • Example: --validateInputToSchema=false --validateOutputToSchema=false --xslTransform=true --generateContents=true

  • Where are your source files? (This should be an absolute path to the root of your source XML directory tree.)

  • Example: --sourcePath=/MyProjects/sqlDocProject/code/XMLsrc

  • Where do you want to store the output HTML files? (This should be an absolute path to the root of your target directory tree.)
  • Example: --targetPath=/MyProjects/sqlDocProject/code/newdoc

  • 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.
  • Example: --xslParmList=revdate:2007.11.01,copyright:2007,relVersion:0.95

  • 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.
  • Example: --contentsToParent=false

  • 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.
  • Example: --groupPlaceHolder=cc: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:
  • <h2>StoredProcedures</h2> <cc:files group="sp"/> <h2>Functions</h2> <cc:files group="fn"/>

    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:

    <h2>StoredProcedures</h2> <cc:files group="sp"> <cc:file> <cc:relfile>SP_map.html</cc:relfile> <cc:absfile> C:/usr/ms/devel/sql/doc/SP_map.xml </cc:absfile> </cc:file> </cc:files> <h2>Functions</h2> <cc:files group="fn"> <cc:file> <cc:relfile>FN_list2table.html</cc:relfile> <cc:absfile> C:/usr/ms/devel/sql/doc/FN_list2table.xml </cc:absfile> </cc:file> <cc:file> <cc:relfile>FN_list2tableIndexed.html</cc:relfile> <cc:absfile> C:/usr/ms/devel/sql/doc/FN_list2tableIndexed.xml </cc:absfile> </cc:file> </cc:files>

    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.

    Example: --groupIdXpath=cc:cleanCodeDoc/cc:head/cc:group

    Figure 4. Generating Groups on a Contents Page: Here are the main steps involved in the group generation process.
    Figure 4 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.
  • Example: --generatorNode=cc:generator

  • 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.
  • Example: // to show all module versions VERSION_DIAG=0x800 // to show all configuration options INPUTOPTIONS_DIAG=0x400 // to show program-specific details XMLTRANSFORM_A_DIAG=0x2 XMLTRANSFORM_B_DIAG=0x4 XMLTRANSFORM_C_DIAG=0x8 XMLTRANSFORM_D_DIAG=0x10 XMLTRANSFORM_E_DIAG=0x20 XMLTRANSFORM_F_DIAG=0x40

    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] ):

    Example: DIAG_LEVEL=0x00A

    The final component for diagnostic setup is specifying where to deliver the output. You have four channels (stdout, stderr, logfile, 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:

    Example: // send to log file (8) and stdout (1) OUTPUT_DIAG=9 // send to log file (8) and stderr (2) OUTPUT_ERR=0xA

Author's Note: Complete details of the Diagnostic API used are available here.

Run, XML, Run
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 @XmlTransform_params.dat

Here's the diagnostic output for the SQL documentation generation:

Processing . (level=0) XmlTransform.isGeneratedFile> scanning candidate contents: index.xml DocumentPlus> VERSION DocumentPlus 9 [contents] processing index.xml: one or more files newer than output file Generating contents file (3 files): \devx\sqlDoc\sqlDocProject\XMLsrc\index.xml Scanning contents template Contents file complete: \devx\sqlDoc\sqlDocProject\XMLsrc\index.xml XmlTransform.dirHasChanged> files added in /devx/sqlDoc/sqlDocProject/api/sql [XSL] processing index.html: input file is newer than output file Loading XSL for level 0: translate.xsl XslQualifier> VERSION XslQualifier 9 [XSL] index.html[~~FN_list2table.html]: converted @ Wed Oct 24 14:05:38 PDT 2007 [XSL] processing FN_list2table.html: output file does not yet exist [XSL] FN_list2table.html[ index.html~~FN_list2tableIndexed.html]: converted @ Wed Oct 24 14:05:39 PDT 2007 [XSL] processing FN_list2tableIndexed.html: input file is newer than output file [XSL] FN_list2tableIndexed.html[ FN_list2table.html~~SP_map.html]: converted @ Wed Oct 24 14:05:39 PDT 2007 [XSL] processing SP_map.html: files added or deleted in current directory [XSL] SP_map.html[FN_list2tableIndexed.html~~]: converted @ Wed Oct 24 14:05:39 PDT 2007 === 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 (0x400) 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 yields 0x40A. 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.

Michael Sorens is a freelance software engineer, spreading the seeds of good design wherever possible, including through his open-source web site, teaching (University of Phoenix plus community colleges), and writing (contributed to two books plus various articles). With BS and MS degrees in computer science and engineering from Case Western Reserve University, he has worked at Fortune 500 firms and at startups, using C#, SQL, XML, XSL, Java, Perl, C, Lisp, PostScript, and others. His favorite project: designing and implementing the world's smallest word processor, where the medium was silicon, the printer "head" was a laser, and the Declaration of Independence could literally fit on the head of a pin. You can discuss this or any other article by Michael Sorens here.
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



We have made updates to our Privacy Policy to reflect the implementation of the General Data Protection Regulation.
Thanks for your registration, follow us on our social networks to keep up-to-date