我在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有没有现成的库或方法?
发布于 2019-05-07 20:51:56
我最终实现了第二种方法,使用jaxb将XSD转换为java模型,然后使用Jackson将模式写入文件。
Gradle:
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进行更多的定制,但是可以做到。
发布于 2019-05-07 17:03:45
您遇到的问题是,您正在对多步转换应用推理工具。正如您已经发现的,推理工具本质上是繁琐的,并不是在所有情况下都能工作。这有点像玩Chinese whispers --链中的每一步都有潜在的损失,所以你从另一端得到的可能是乱码。
基于您建议的替代方法,我将建议一个类似的解决方案:
很明显,OpenAPI是一个应用编程接口定义标准。您应该可以采用代码优先的方法,在代码中组合API操作并公开从XJB生成的类型。然后,您可以使用Apiee及其注释来生成OpenAPI定义。这假设您的应用编程接口使用的是JAX-RS。
这仍然是一个两步走的过程,但成功的机会更高。这里的好处是您的第一步,将您的XSD类型推断为java类型,希望对定义您的API操作的代码影响很小(如果有的话)。尽管仍然会有一个手动的步骤(更新模型),但是一旦代码被重新构建,OpenAPI定义就会自动更新。
https://stackoverflow.com/questions/56018335
复制相似问题