Как создать сгенерированные классы содержат Javadoc из документации XML Schema
В настоящее время я работаю с XML-схемой, которая имеет <xsd:annotation>
/<xsd:documentation>
для большинства типов и элементов. Когда я генерирую Java Beans из этой XML-схемы, Javadoc из этих Beans содержит только общую генерированную информацию о разрешенном содержимом типа/элемента.
Я хотел бы видеть содержимое тега <xsd:documentation>
в соответствующих местах (например, содержимое этого тега для contentxtType должно отображаться в Javadoc класса, сгенерированного для представления этого complexType).
Есть ли способ достичь этого?
Изменить: эта XML-схема будет использоваться в WSDL с JAX-WS, поэтому этот тег также может быть подходящим.
Изменить 2. Я читал о <jxb:javadoc>
. Насколько я понимаю, я могу указать это либо в отдельном файле привязки JAXB, либо непосредственно в XML-схеме. Это почти решило бы мою проблему. Но я бы предпочел использовать существующий тег <xsd:documentation>
, поскольку Javadoc не является основной целью документации (это информация о структуре данных в первую очередь, а не о Java Beans, сгенерированном из нее), и разрешить инструменты без JAXB для доступа к информации. Предоставление документации в <jxb:javadoc>
и xsd:documentation>
"кажется" неправильным, потому что я не дублирую данные (и работаю) без уважительной причины.
Изменить 3. Благодаря ответу Паскаля я понял, что у меня уже есть половина решения: <xsd:documentation>
of complexType
записывается в начало его Javadoc! Проблема по-прежнему заключается в том, что используется только complexType
и simpleType
(что также может привести к классу), а элементы все еще Javadoc-less.
Ответы
Ответ 1
Мне никогда не приходилось устанавливать регулярные xsd:documentation
в исходный код java, кроме , если и только если это сложный тип. Документация для элементов, простых типов,
и т.д. игнорируются.
Итак, я использую 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 - это либо "класс", либо "свойство".
Для пакета вы пишете дочерний элемент 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[ --- ]]>
(EDIT: при написании моего ответа вопрос был отредактирован OP, поэтому я обновляю его соответствующим образом)
В моем случае javadoc был единственной целью, поэтому было приемлемо использовать jxb:javadoc
. Но ваше обновление имеет прекрасный смысл, и, на самом деле, я полностью согласен с вами. К сожалению, я никогда не нашел идеального решения для ситуации, которую вы описали (поэтому я буду внимательно следить за этим вопросом). Возможно, вы могли бы использовать что-то вроде xframe для создания документации из xsd:documentation
, но это не отвечает на вопрос.
Ответ 2
Это невозможно с помощью эталонной реализации JAXB. Даже если вы попытаетесь написать плагин XJC, вы обнаружите, что API-интерфейс плагина не имеет никакого отношения к определению схемы, поэтому нет способа извлечь эту информацию.
Нашей единственной надеждой является то, что будущая версия JAXB исправляет ситуацию. Здесь откройте запрос функции здесь.
Ответ 3
Я считаю, что следующие методы очень хорошо работают для добавления заголовков JavaDoc в классы Java-классов (сгенерированные из XML-схем). Я устанавливаю JavaDoc в теги, определенные в пространстве имен jax-b, вложенные в аннотации схемы xml и теги appinfo. Обратите внимание, что пространство имен jaxb определяет типы тегов документации; Я использую два из них: класс и теги свойств. определенный в следующем пространстве имен: xmlns: 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 <p> 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>
<p>Documentation goes here.</p>
</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>
<p>Documentation goes here.</p>
</jxb:javadoc>
</jxb:property>
</xs:appinfo>
</xs:annotation>
</xs:attribute>
4) Чтобы документировать выбор, я использую тэг jaxb свойства, и я документирую выбор.
<xs:choice maxOccurs="unbounded">
<xs:annotation>
<xs:appinfo>
<jxb:property>
<jxb:javadoc>
<p>Documentation goes here.</p>
</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
Специально для этого случая я написал XJC-плагин xjc-documents-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
И получил класс как (геттеры, сеттеры и любые аннотации опущены для простоты):
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-класс с плагином в run classpath и просто добавьте опцию -XPluginDescriptionAnnotation
. Fe:
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' ]
}
Завершите пример gradle
в gradle
example -project-gradle проекта.