Import XSD to OpenAPI



我在XSD文件中有一些模型定义,我需要从OpenApi定义中引用这些模型。手动重塑是没有选择的,因为文件太大,我需要将其放入构建系统中,以便在 XSD 发生更改时,我可以为 OpenAPI 重新生成模型/模式。

我尝试过并且几乎有效的是使用 xsd2json,然后使用节点模块 json-schema-to-openapi 将其转换。然而,xsd2json正在放弃一些complexElement模型。例如,"$ref": "#/definitions/tns:ContentNode"在一个模型内部用作子类型,但架构中没有ContentNode的定义,当我查看XSD时,ContentNode有一个complexElement定义。

另一种我还没有尝试但对我来说似乎有点过分的方法是使用 xjb 从 XSD 生成 Java 模型,然后使用 JacksonSchema 生成 json 模式。

是否有任何已建立的库或方法,在OpenApi中使用XSD?

我最终实现了第二种方法,使用 jaxb 将 XSD 转换为 java 模型,然后使用 Jackson 将模式写入文件。

格拉德尔:

plugins {
id 'java'
id 'application'
}
group 'foo'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
compile group: 'com.fasterxml.jackson.module', name: 'jackson-module-jsonSchema', version: '2.9.8'
}
configurations {
jaxb
}
dependencies {
jaxb (
'com.sun.xml.bind:jaxb-xjc:2.2.7',
'com.sun.xml.bind:jaxb-impl:2.2.7'
)
}
application {
mainClassName = 'foo.bar.Main'
}
task runConverter(type: JavaExec, group: 'application') {
classpath = sourceSets.main.runtimeClasspath
main = 'foo.bar.Main'
}
task jaxb {
System.setProperty('javax.xml.accessExternalSchema', 'all')
def jaxbTargetDir = file("src/main/java")
doLast {
jaxbTargetDir.mkdirs()
ant.taskdef(
name: 'xjc',
classname: 'com.sun.tools.xjc.XJCTask',
classpath: configurations.jaxb.asPath
)
ant.jaxbTargetDir = jaxbTargetDir
ant.xjc(
destdir: '${jaxbTargetDir}',
package: 'foo.bar.model',
schema: 'src/main/resources/crs.xsd'
)
}
}
compileJava.dependsOn jaxb

使用转换器主类,它可以执行以下操作:

package foo.bar;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.module.jsonSchema.JsonSchema;
import com.fasterxml.jackson.module.jsonSchema.JsonSchemaGenerator;
import foo.bar.model.Documents;
public class Main {
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
try {
JsonSchema schema = schemaGen.generateSchema(Documents.class);
System.out.print(mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));
} catch (JsonMappingException e) {
e.printStackTrace();
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}

不过,它仍然不完美,...这将需要遍历所有模型类并生成包含架构的文件。此外,它不使用引用,如果一个类具有另一个类的成员,则架构将以内联方式打印而不是引用。这需要使用SchemaFactoryWrapper进行更多自定义,但可以完成。

您遇到的问题是您在多步骤转换上应用推理工具。正如您所发现的,推理工具本质上是挑剔的,并非在所有情况下都有效。这有点像玩中国人的耳语——链条的每一步都有潜在的损失,所以你从另一端得到的东西可能会乱码。

根据您建议的替代方法,我建议类似的解决方案:

很明显,OpenAPI是一个API定义标准。您应该可以采用代码优先的方法,在代码中编写 API 操作并公开从 XJB 生成的类型。然后,您可以使用 Apiee 及其注释来生成 OpenAPI 定义。这假设您正在为您的 API 使用 JAX-RS。

这仍然是一个两步走的过程,但成功的机会更高。这样做的好处是,第一步,将XSD类型推断为java类型,希望对定义API操作的代码产生很小(如果有的话)影响。尽管仍然会有一个手动步骤(更新模型),但一旦代码被重建,OpenAPI 定义就会自动更新。

最新更新