我有 2 个 xsd 模式,我使用 maven-jaxb2-plugin 从中生成一个类消息。主要的 xsd 是 message.xsd,它导入 common.xsd,其中包含一些常见类型。然而两者都有不同的目标命名空间。
这会导致 jaxb xml unmarshaller 无法读取 xml 中的字段并使用默认值。如果在生成的类中我手动将命名空间设置为“消息”,它就可以工作。有没有办法将两个生成的类字段放置在同一名称空间下?或者我的 XML 消息可能是错误的?或者我是否在某处缺少 jaxb2 生成器参数?我应该使用 jaxb 绑定来解决这个问题吗?
我无法更改 xsd 命名空间定义。很多答案都非常接近我需要的,但没有一个是我遇到的实际问题。
这会生成一个看起来像这样的 Message 类:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"computer"
})
@XmlRootElement(name = "message", namespace = "message")
public class Message implements ToString2
{
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
"date",
"info"
})
public static class Computer implements ToString2
{
@XmlElement(namespace = "message", required = true)
protected int date;
@XmlElement(name = "info", namespace = "message", required = true)
protected InfoType info;
}
}
Info 类是从 common.xsd 生成的,它看起来像这样:
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "InfoType", propOrder = {
"number",
"id"
})
public class InfoType implements ToString2
{
@XmlElement(namespace = "")
@XmlSchemaType(name = "integer")
protected int number;
@XmlElement(namespace = "")
@XmlSchemaType(name = "integer")
protected int id;
}
我发送此 xml:
<?xml version="1.0" encoding="utf-8"?>
<message xmlns="message">
<computer>
<info>
<name>2</name>
<id>999998</id>
</info>
<date>20220508</date>
</computer>
</message>
package-info.java 将命名空间设置为“common”,这就是为什么我假设 Info 中字段的命名空间是“”,它看起来像这样:
@javax.xml.bind.annotation.XmlSchema(namespace = "common", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.myapp.message
pom:
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.14.0</version>
<dependencies>
<dependency>
<groupId>org.glassfish.jaxb</groupId>
<artifactId>jaxb-runtime</artifactId>
<version>2.3.3</version>
</dependency>
</dependencies>
<configuration>
<accessExternalSchema>all</accessExternalSchema>
<specVersion>2.1</specVersion>
<cleanPackageDirectories>false</cleanPackageDirectories>
<extension>true</extension>
<args>
<arg>-Xfluent-api</arg>
<arg>-XtoString</arg>
</args>
<plugins>
<plugin>
<groupId>net.java.dev.jaxb2-commons</groupId>
<artifactId>jaxb-fluent-api</artifactId>
<version>${maven-jaxb2-plugin.fluent-api.version}</version>
</plugin>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>${jaxb2-basics-runtime.version}</version>
</plugin>
</plugins>
</configuration>
<executions>
<execution>
<id>generate-message</id>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/message</schemaDirectory>
<schemaIncludes>
<include>message.xsd</include>
</schemaIncludes>
<bindingDirectory>src/main/resources/jaxb</bindingDirectory>
<generateDirectory>target/generated-sources/jaxb/message</generateDirectory>
<generatePackage>com.myapp.message
</generatePackage>
</configuration>
</execution>
</executions>
</plugin>
从其他 xsd 代中,我假设将 targetNamespace 更改为相同的命名空间并使用 include 而不是 import 可以解决问题,但这不是一个选项。
手动更改 @XmlElement(namespace = "") 中的命名空间解决了问题,但这对我来说没有多大作用,因为它会在下一代被重写。
我尝试调查xjb。但是我不确定这是否真的是这样,如果我将其设置为绑定到顶部元素,它在解析 commons.xsd 中的类型时会遇到麻烦 - 可能值得追求?
我们没有
common.xsd
一代,但我认为您不应该将公共内容和消息生成到同一个包中(标签 generatePackage
)。
通过这样做,Jaxb 不知道哪个包注释是正确的。
您还可以按照升级指南
升级到至少v2版本的maven-jaxb2-plugin