如何使生成的类包含 XML Schema 文档中的 Javadoc

Posted

技术标签:

【中文标题】如何使生成的类包含 XML Schema 文档中的 Javadoc【英文标题】:How to make generated classes contain Javadoc from XML Schema documentation 【发布时间】:2010-12-11 15:17:58 【问题描述】:

我目前正在使用在大多数类型和元素上具有 <xsd:annotation>/<xsd:documentation> 的 XML 架构。当我从这个 XML Schema 生成 Java Bean 时,这些 Bean 的 Javadoc 只包含一些关于类型/元素允许内容的通用生成信息。

我想在相关位置查看<xsd:documentation> 标记的内容(例如,complextType 的标记内容应显示在生成的用于表示该 complexType 的类的 Javadoc 中)。

有什么办法可以做到吗?

编辑:此 XML Schema 将在带有 JAX-WS 的 WSDL 中使用,因此此标记也可能是合适的。

编辑 2:我读过关于 <jxb:javadoc> 的信息。据我了解,我可以在单独的 JAXB 绑定文件中或直接在 XML 模式中指定。这几乎可以解决我的问题。但我宁愿使用现有的<xsd:documentation> 标记,因为 Javadoc 不是文档的主要目标(它主要是关于数据结构的信息,而不是关于从中生成的 Java Beans)并允许非 JAXB 工具访问信息也是如此。在<jxb:javadoc>xsd:documentation> 中提供文档“感觉”是错误的,因为我无缘无故地复制数据(和工作)。

编辑 3:感谢 Pascal 的回答,我意识到我已经有了一半的解决方案:complexTypes 的 <xsd:documentation> 被写入其 Javadoc 的开头!问题仍然是使用了complexTypes 和simpleTypes(也可以产生一个类)和元素仍然没有Javadoc。

【问题讨论】:

是否使用 选项? @Pascal:谢谢,我已经在问题中回答了。 【参考方案1】:

特别是我写了 XJC 插件xjc-documentation-annotation-plugin。

它的作用:<annotation><documentation> -> Java 类注解

说我们有XSD中描述的这个对象:

<xs:complexType name="CadastralBlock">
    <xs:annotation>
        <xs:documentation>Cadastral quarter</xs:documentation>
    </xs:annotation>
    <xs:sequence>
        <xs:element name="number" type="xs:string">
            <xs:annotation>
                <xs:documentation>Cadastral number</xs:documentation>
            </xs:annotation>
        </xs:element>
</xs:complexType>

我们像这样运行 xjc:

xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated scheme.xsd

得到了类似的类(为简单起见,省略了getter、setter和任何注释):

public class CadastralBlock 
    protected String number;

但就我而言,我想知道如何在源文件中命名类和字段!所以这个插件就是这样做的!

所以你得到:

@XsdInfo(name = "Cadastral quarter", xsdElementPart = "<complexType name=\"CadastralBlock\">\n  <complexContent>\n    <restriction base=\"http://www.w3.org/2001/XMLSchemaanyType\">\n      <sequence>\n        <element name=\"number\" type=\"http://www.w3.org/2001/XMLSchemastring\"/></sequence>\n      </restriction>\n  </complexContent></complexType>")
public class CadastralBlock 
    @XsdInfo(name = "Cadastral number")
    protected String number;

如何使用

在命令行中手动调用

如果您想手动运行它,请确保运行类路径中带有插件的 jar 类,只需添加选项-XPluginDescriptionAnnotation。 F.e.:

xjc -npa -no-header -d src/main/generated-java/ -p xsd.generated -XPluginDescriptionAnnotation scheme.xsd

从 Java/Groovy 调用

Driver.run(
    [
        '-XPluginDescriptionAnnotation'
        ,'-d', generatedClassesDir.absolutePath
        ,'-p', 'info.hubbitus.generated.test'
        ,'CadastralBlock.xsd'
    ] as String[]
    ,new XJCListener() ...
)

参见测试 XJCPluginDescriptionAnnotationTest 示例。

从 Gradle 中使用

gradle-xjc-plugin:

plugins 
    id 'java'
    id 'org.unbroken-dome.xjc' version '1.4.1' // https://github.com/unbroken-dome/gradle-xjc-plugin


...

dependencies 
    xjcClasspath 'info.hubbitus:xjc-documentation-annotation-plugin:1.0'


// Results by default in `build/xjc/generated-sources`
xjcGenerate 
    source = fileTree('src/main/resources')  include '*.xsd' 
    packageLevelAnnotations = false
    targetPackage = 'info.hubbitus.xjc.plugin.example'
    extraArgs = [ '-XPluginDescriptionAnnotation' ]

在项目的example-project-gradle 目录中完成gradle 示例。

【讨论】:

为什么有人减答案?我可以增强提供的解决方案吗?【参考方案2】:

这在 JAXB 参考实现中是不可能的。即使您尝试编写 XJC 插件,您也会发现插件 API 没有引用 Schema 定义,因此无法提取此信息。

我们唯一的希望是未来版本的 JAXB 可以解决这种情况。有一个open feature request here。

【讨论】:

该链接需要登录。 :-( 问题链接已失效,因为javaee/jaxb-v2 是an archived repo 并且没有问题选项卡;新的仓库位于eclipse-ee4j/jaxb-ri,相关问题为#273 和#460 和【参考方案3】:

我发现以下技术非常适合将 JavaDoc 标头添加到 Java 元素类(从 XML 模式生成)。我将 JavaDoc 嵌套在 jax-b 命名空间中定义的标记中,嵌套在 xml 模式注释和 appinfo 标记中。注意 jaxb 命名空间定义了文档标签的类型;我使用其中的两个:类和属性标签。在以下命名空间中定义:xmlns:jxb="http://java.sun.com/xml/ns/jaxb"

1) 为了记录一个类,我按以下顺序使用 jaxb“类”标签:

  <xs:complexType name="Structure">
     <xs:annotation>
        <xs:appinfo>
           <jxb:class>
              <jxb:javadoc>
                 Documentation text goes here. Since parsing the schema  
                 into Java involves evaluating the xml, I escape all 
                 the tags I use as follows &lt;p&gt; for <p>.
              </jxb:javadoc>
           </jxb:class>
        </xs:appinfo>
     </xs:annotation>

     .
     .
     .
  </xs:complexType>

2)为了记录一个元素,我使用“property”标签如下:

       <xs:element name="description" type="rep:NamedString">
          <xs:annotation>
             <xs:appinfo>
                <jxb:property>
                   <jxb:javadoc>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </jxb:javadoc>
                </jxb:property>
             </xs:appinfo>
          </xs:annotation>
       </xs:element>

3) 我使用同一组标签来记录属性:

      <xs:attribute name="name" type="xs:NCName" use="required">
          <xs:annotation>
             <xs:appinfo>
                <jxb:property>
                   <jxb:javadoc>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </jxb:javadoc>
                </jxb:property>
             </xs:appinfo>
          </xs:annotation>
       </xs:attribute>

4) 为了记录选择,我使用属性 jaxb 标记,并记录选择。

    <xs:choice maxOccurs="unbounded">
          <xs:annotation>
             <xs:appinfo>
                <jxb:property>
                   <jxb:javadoc>
                      &lt;p&gt;Documentation goes here.&lt;/p&gt;
                   </jxb:javadoc>
                </jxb:property>
             </xs:appinfo>
          </xs:annotation>

          <xs:element name="value" type="rep:NamedValue" />
          <xs:element name="list" type="rep:NamedList" />
          <xs:element name="structure" type="rep:NamedStructure" />
       </xs:choice>

尝试在此处记录个人选择会失败,因为此标签 生成一个无类型列表。

【讨论】:

【参考方案4】:

我从来没有能够将常规的xsd:documentation 放在 java 源代码中,除非当且仅当它是一个复杂类型。元素、简单类型的文档, 等被忽略。

所以,我最终使用了jxb:javadoc。为此,请在 &lt;xsd:schema&gt; 元素中包含 xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 的定义。

将孩子添加到&lt;xsd:complexType&gt;&lt;xsd: element&gt;&lt;xsd:attribute&gt;

<xsd:annotation><xsd:appinfo><jxb:XXX><jxb:javadoc>
  This is my comment for a class/property
</jxb:javadoc></jxb:XXX></xsd:appinfo></xsd:annotation>

其中 XXX 是“类”或“属性”。

对于一个包你写一个孩子到xsd:schema

<xsd:annotation><xsd:appinfo><jxb:schemaBindings><jxb:package name="com.acme"><jxb:javadoc>
  This is my comment for a package
</jxb:javadoc></jxb:package></jxb:schemaBindings></xsd:appinfo></xsd:annotation>

编写 html 文档需要用 &lt;![CDATA[ --- ]]&gt; 括起来

(编辑:在写我的答案时,问题已由 OP 编辑​​,因此我正在相应地更新它)

在我的例子中,javadoc 是唯一的目标,所以使用jxb:javadoc 是可以接受的。但是您的更新非常有意义,实际上,我完全同意您的看法。可悲的是,我从来没有为你描述的情况找到一个理想的解决方案(所以我会非常仔细地关注这个问题)。也许您可以使用xframe 之类的东西从xsd:documentation 生成文档,但这并不能回答问题。

【讨论】:

嗯,我没有意识到(至少)complexTypes 获得了 Javadoc。这离我喜欢的东西又近了一小步,但还不够完美。 glassfish.10926.n7.nabble.com/… 您可能还需要将其添加到 xml 顶部的架构行:jxb:version="2.1"

以上是关于如何使生成的类包含 XML Schema 文档中的 Javadoc的主要内容,如果未能解决你的问题,请参考以下文章

在xml spy中怎样将xml文档转化为 Schema文档

Maven 中的 XML DTD/Schema 验证

懂XML的进!

C#实体类生成XML与XML Schema文档

Schema约束

xml约束技术---schema