代码之家  ›  专栏  ›  技术社区  ›  Joachim Sauer

如何使生成的类包含来自XML模式文档的javadoc

  •  43
  • Joachim Sauer  · 技术社区  · 15 年前

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

    我想看看 <xsd:文档> 标记在相关位置(例如,complexType的标记内容应显示在为表示该complexType而生成的类的javadoc中)。

    有什么方法可以做到这一点吗?

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

    编辑2 :我读过 <jxb:javadoc> . 根据我的理解,我可以在单独的JAXB绑定文件中或直接在XML模式中指定。那几乎可以解决我的问题。但我宁愿用现有的 <xsd:文档> TAG,因为Javadoc不是文档的主要目标(它主要是关于数据结构的信息,而不是从它生成的Java bean),并且允许非JAXB工具访问这些信息。提供两种文件 <JXB: JavaDoc & GT; xsd:documentation> “感觉”是错误的,因为我复制数据(和工作)没有好的理由。

    编辑3 :多亏了帕斯卡的回答,我才意识到我已经有了一半的解决方案: <xsd:文档> 属于 complexType S写在它的javadoc的开头!问题仍然是 只有 那个 复合型 使用S和 simpleType s(也可以生成一个类)和元素仍然是不含javadoc的。

    4 回复  |  直到 5 年前
        1
  •  35
  •   Pascal Thivent    15 年前

    我从来没能正常过 xsd:documentation 放置在Java源代码中 当且仅当 这是一种复杂的类型。元素、简单类型的文档, ETC被忽略。

    所以,我最终使用 jxb:javadoc . 为此,包括 xmlns:jxb="http://java.sun.com/xml/ns/jaxb" 在你 <xsd:schema> 元素。

    添加一个孩子 <xsd:complexType> <xsd: element> <xsd:attribute> :

    <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是“class”或“property”。

    为了一个包裹你写一个孩子 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文档需要用括号括起来 <![CDATA[ --- ]]>

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

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

        2
  •  11
  •   Peter    7 年前

    这对于JAXB引用实现是不可能的。即使您试图编写一个XJC插件,您也会发现插件API没有引用模式定义,因此无法提取此信息。

    我们唯一的希望是JAXB的未来版本能够解决这个问题。有一个 open feature request here .

        3
  •  4
  •   John Spragge    8 年前

    我发现以下技术可以很好地将JavaDoc标头添加到Java元素类(由XML架构生成)。我将javadoc嵌套在JAX-B名称空间中定义的标记中,嵌套在XML模式注释和appinfo标记中。注意,JAXB名称空间定义了文档标记的类型;我使用其中的两个:类和属性标记。在以下命名空间中定义:xml ns:jxb=“http://java.sun.com/xml/ns/jaxb”

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

      <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
  •  -1
  •   Hubbitus    5 年前

    尤其是在这种情况下,我编写了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/XMLSchema}anyType\">\n      <sequence>\n        <element name=\"number\" type=\"{http://www.w3.org/2001/XMLSchema}string\"/></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
    

    从爪哇/ Groovy打电话

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

    例如,请参见测试XJCpluginDescriptionNotationTest。

    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' ]
    }
    

    完成 gradle example-project-gradle 项目目录。