Vincent.Chan‘s Blog

常用链接

统计

积分与排名

网站

最新评论

技巧:XML 格式的 Javadoc::为报表使用 XML 格式的 Javadoc 输出

级别: 中级

Jack Herrington, 主编, Code Generation Network

2005 年 5 月 16 日

在 Java 代码中蕴涵着许多有价值的信息:所有类和接口,以及它们的实例变量和方法。您可以使用这些数据来创建文档,构建代码生成器,或者为项目报表提供度量标准。

Javadoc 是一个非常分解良好的应用程序。很多人认为它只是一个从一组 Java™ 文件中读取代码和注释来创建 HTML 的程序。但事实上,这款工具分为两个部分。第一部分是代码分析引擎,用来解析代码和注释。第二部分生成 HTML,但结果是,您可以使用称为 doclets 的扩展来改变这一部分。

对于本技巧,我使用 JELDoclet(参阅 参考资料) 从一组测试 Java 文件生成一个 XML 输出文件。然后,再使用 XSL 把这个 XML 文件格式化成一个简单的 HTML 文件。该 HTML 文件展示了 XML 文件所包含的数据。

下载 JELDoclet 后,使用下面的命令语法在一组文件上运行 JELDoclet:

												
														
javadoc -doclet JELDoclet -docletpath .. *.java

JELDoclet 的 test 目录包含一组测试 Java 文件。这个命令解析 test 目录中的所有 Java 文件,并且创建一个称为 out.xml 的文件。这个文件包含了 Javadoc 树中的所有信息。清单 1 展示了这个输出 XML 文件的一部分。


清单 1. JELDoclet 输出 XML 文件
												
														

<jel>
<class superclass="Object" name="MyInterClass">
<extend name="MyInterface">
</extend>
<comment>
My interface implemented
</comment>
<fields>
<field visibility="protected"
fulltype="java.lang.String"
type="String" name="_prot_string">
<comment>
A protected string
</comment>
</field>
<field visibility="public"
fulltype="java.lang.String"
type="String" name="_pub_string">
<comment>
A public string
</comment>
</field>
</fields>
<methods>
<constructor visibility="public" name="MyInterClass">
<comment>
A no-argument constructor
</comment>
</constructor>
<constructor visibility="public" name="MyInterClass">
<params>
<param fulltype="java.lang.String"
type="String" comment="A string."
name="aString">
</param>
...

jel 标签包含了一系列 class 标签 —— 每个类对应一个。在 class 标签中是字段、方法和构造函数。XML 文件也包含相关的注释。

从 XML 创建 HTML

为这个 XML(清单 1中)生成 HTML 的第一步是从清单 2 中的基本标签模板开始。


清单 2. 基本 HTML 模板
												
														

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl=http://www.w3.org/1999/XSL/Transform
version="2.0">

<xsl:output method="html" />

<xsl:template match="/">
<html><head><title>XDoclet output</title>
<xsl:call-template name="css" />

</head>
<body>
<xsl:for-each select="/jel/class">

<h1>
<xsl:choose>
<xsl:when test="@abstract='true'">Interface:
<xsl:value-of select="@name" /></xsl:when>
<xsl:otherwise>Class
: <xsl:value-of select="@name" />
( <xsl:value-of select="@superclass" /> )
</xsl:otherwise>
</xsl:choose>
</h1>

<h2>Instance Variables</h2>
<xsl:apply-templates select="fields/field" />

<h2>Constructors</h2>
<xsl:apply-templates select="methods/constructor" />

<h2>Methods</h2>
<xsl:apply-templates select="methods/method" />

<hr/>
</xsl:for-each>
</body>
</html>
</xsl:template>

在清单 2 的开始,我创建了 html 根标签和 head 部分。然后,我迭代了输入文件中的每个类。对于每个类,我在 h1 标签中输出类或接口的名称,并为 fieldsconstructorsmethods 应用模板。接着,我通过结束 bodyhtml 标签而结束整个清单。

用于构建字段 HTML 的模板非常简单,如清单 3 所示。


清单 3. 字段模板
												
														

<xsl:template match="field">
<p class="field">
<xsl:value-of select="@visibility" />
<xsl:text> </xsl:text>
<xsl:value-of select="@type" />
<xsl:text> </xsl:text>
<xsl:value-of select="@name" />
</p>
</xsl:template>

简洁的内容:我只输出了可见性、类型和名称。我使用了一个带有 class 字段的 paragraph 标签把它们括起来。后面在 CSS 中将用到 class 字段。

方法和构造函数模板与字段模板类似,如清单 4 所示。


清单 4. 方法和构造函数模板
												
														

<xsl:template match="method">
<p class="method">
<xsl:value-of select="@visibility" />
<xsl:text> </xsl:text>
<xsl:value-of select="@type" />
<xsl:text> </xsl:text>
<xsl:value-of select="@name" />(
<xsl:apply-templates select="params" />
)</p>
</xsl:template>

<xsl:template match="constructor">
<p class="method">
<xsl:value-of select="@visibility" />
<xsl:text> </xsl:text>
<xsl:value-of select="@name" />(
<xsl:apply-templates select="params" />
)</p>
</xsl:template>

这里惟一的诀窍是,我需要将参数列表输出到每个构造函数或方法中。我使用 xsl:apply-templates 标签来处理,这个标签用来为 params 标签找到正确的模板 —— 在本例中,清单 5 展示了这个模板。


清单 5. 参数模板
												
														

<xsl:template match="params">
<xsl:for-each select="param">
<xsl:if test="position()>1">, </xsl:if>
<xsl:value-of select="@type" /><xsl:text> </xsl:text>
<xsl:value-of select="@name" />
</xsl:for-each>
</xsl:template>

这里最吸引人的地方是,我想要在列表中的两个参数间插入逗号。因此我使用 xsl:if 命令,在第 2 个参数或后面的参数上插入逗号。

XSL 模板的最后一部分是 CSS,它使输出内容更加容易阅读(参阅清单 6)。


清单 6. CSS 模板
												
														

<xsl:template name="css">
<style>
body { font-family: Arial, Verdana, sans serif;

font-size: small; }
.method, .field { padding-left:50px; }
</style>
</xsl:template>

</xsl:stylesheet>

使用诸如 Arial 或 Verdana 这样的 sans-serif 字体,以使输出更加容易阅读。您可能使用的是 Courier 字体,但是我认为它会使页面看起来非常单调,并且让人觉得好像是用古老的打印机输出来的。最后,输出的结果看起来像图 1 那样。


图 1. 浏览器显示的最终 HTML
最终 HTML




回页首


结束语

格 式化 HTML 仅仅是您可以对 Javadoc 工具的 XML 输出所做的事情之一。您可以像 XDoclet 所做的一样,使用 Javadoc 树中的信息(这里导出为 XML)来加强代码生成器的功能。您可以像 Eclipse 或 IntelliJ 一样,执行代码引用分析和重构。您也可以得到关于代码基的度量标准。获得 Java 代码完整的、结构化的 XML 表示,有助于提高您的生产力。





回页首


参考资料





回页首


关于作者


Jack Herrington 是一名有着 20 多年工作经验的杰出工程师,现任 Code Generation Network 公司的主编。他同时也是 Code Generation in Action 一书的作者。您可以通过电子邮件 jack_d_herrington@codegeneration.net 与他联系。

posted on 2006-03-21 23:43 Vincent.Chen 阅读(400) 评论(0)  编辑  收藏 所属分类: XML


只有注册用户登录后才能发表评论。


网站导航: