【问题标题】:I want to add a Schema annotation via Javafx to the package-info.java我想通过 Javafx 将 Schema 注释添加到 package-info.java
【发布时间】:2021-10-24 19:39:22
【问题描述】:

所以我有一个特定的 Schema 注释需要添加到 package-info.java 中。我尝试了几件事并在线搜索了答案,但找不到任何适用于我的问题的答案。

包装信息.java:

@javax.xml.bind.annotation.XmlSchema(
          ...
        )
package my.package.name;

我想要的 XmlSchema:

<databaseChangeLog
    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">
</databaseChangeLog>

我的问题是,@javax.xml.bind.annotation.XmlSchema(...) 中必须包含什么内容才能实现此架构?

【问题讨论】:

  • 我认为你需要 jaxb。搜索它的教程。您可以使用它根据您的 xml 架构生成 java 类。
  • @只是另一个Java程序员对于我使用Jaxb的类,但是这种特殊情况不能用jaxb完成,至少据我所知,这就是我尝试这样做的原因^^

标签: java xml schema


【解决方案1】:

对于任何有类似问题的人,我找到了解决方案。

这里的 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。发生在我身上,可以通过更好地更改软件包来轻松修复,但因此您不必考虑代码不起作用。

【讨论】:

    猜你喜欢
    • 2012-01-14
    • 1970-01-01
    • 2015-11-04
    • 1970-01-01
    • 2011-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    相关资源
    最近更新 更多