对于任何有类似问题的人,我找到了解决方案。
这里的 Schema 有两个组件,必须在您的代码中设置才能生成,
命名空间:
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
架构位置:
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro
http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd"
namespace 必须使用javax 设置在package-info.java 内
@javax.xml.bind.annotation.XmlSchema(
namespace = "http://www.liquibase.org/xml/ns/dbchangelog",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package de.softproject.x4.server.migration.keycloak.changelog_beans;
但是schemaLocation不能在这里设置,或者至少我还没有找到如何设置。有效的是直接使用jaxb 设置它(我使用 jaxb 作为我的 Java XML 绑定框架,如果您使用的是另一个,则此解决方案将不适用)
JAXBContext jaxbContext = JAXBContext.newInstance(ClassToHaveSchema.class);
Marshaller marshaller = jaxbContext.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION,
"http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-
ext.xsd http://www.liquibase.org/xml/ns/pro
http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-
4.1.xsd");
这里的重要部分是marshaller.setProperty(Marshallar.JAXB_SCHEMA_LOCATION, ...)。当您使用要编组的类设置 JAXB Marshaller 时,这将添加您指定的 xsi:schemaLocation 并自动为您生成 xmlns:xsi(标准命名空间前缀 xsi)
然后,生成的 XML 将具有这样的架构设置:
<ClassToHaveSchema
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro
http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd">
</ClassToHaveSchema>
您的 SchemaLocation 可能比这里更短或更长,它不必是 6 个 URI,但在这种情况下就是这样。
您当然可以创建一个包含此信息作为常量的类:
public class LiquibaseInfo {
public static final String NAMESPACE = "http://www.liquibase.org/xml/ns/dbchangelog";
public static final String SCHEMA_LOCATION = "http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-4.1.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd";
private LiquibaseInfo() {}
}
然后在你的代码中使用常量,这样会更容易理解:
...
namespace = LiquibaseInfo.NAMESPACE
...
...
marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, LiquibaseInfo.SCHEMA_LOCATION);
...
注意:
在 package-info 中设置 namespace 时,此包现在链接到此 namespace。这意味着,例如,如果您在此包中的某个类中解组某些 XML 文件,它使用另一个 namespace,它将无法工作,因为它需要集合 namespace。发生在我身上,可以通过更好地更改软件包来轻松修复,但因此您不必考虑代码不起作用。