操纵 JAXB 以创建 IDREF 元素而不是 JaxBElement<?>

Manipulate JAXB to create IDREF Elements instead of JaxBElement<?>

我想使用 maven-jaxb2-plugin 生成 类。

我的输入 xsd 如下所示:

<complexType>
<complexContent>
    <restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
        <sequence>
            <element name="ReferencedElementA" type="{http://www.w3.org/2001/XMLSchema}IDREFS" minOccurs="0" />
            <element name="ReferencedElementB" type="{http://www.w3.org/2001/XMLSchema}IDREF"
                maxOccurs="unbounded" minOccurs="0" />
        </sequence>
    </restriction>
</complexContent>

请注意,我无法更改架构,因为它是由外部客户提供的!

这是生成的代码:

@XmlList
@XmlElement(name = "ReferencedElementA")
@XmlIDREF
@XmlSchemaType(name = "IDREFS")
protected List<Object> referencedElementA;
@XmlElementRef(name = "ReferencedElementB", namespace = "ABC", type = JAXBElement.class, required = false)
protected List<JAXBElement<Object>> referencedElementB;

如您所见,"ReferencedElementB" 生成为带有 @XMLElementRef-Annotation 的列表。

我想要的是如下内容:

@XmlElement(name = "ReferencedElementB")
@XmlIDREF
@XmlSchemaType(name = "IDREF")
protected List<Object> referencedElementB;

使用 Blaise Doughan 中的解决方法,我使用以下代码扩展了我的绑定文件:

<bindings node = ".//xs:element[@name='ReferencedElementB']">
    <class ref="java.lang.Object"/>
</bindings>

这几乎完成了工作,生成如下代码:

@XmlElement(name = "ReferencedElementB")
@XmlSchemaType(name = "IDREF")
protected List<Object> referencedElementB;

但是,@XmlIDREF-Annotation 仍然缺失。这会在编组期间产生错误。

我尝试通过 annox-plugin 注入缺失的注释:

<bindings node = ".//xs:element[@name='ReferencedElementB']">
    <class ref="java.lang.Object"/>
    <annox:annotate target="field">@javax.xml.bind.annotation.XmlIDREF</annox:annotate>
</bindings>

但是生成失败

compiler was unable to honor this annox:annotate customization. It is attached to a wrong place, or its inconsistent with other bindings

再一次,我无法更改输入 xsd。

提前致谢!

Please note, that i can't alter the schema as it is provided by an external customer!

我一直在 SO 上阅读这篇文章,我总是想知道 - 为什么?为什么不能更改架构?

好吧,当然您可以在编译之前更改架构。采用原始架构并应用 patch/XSLT/whatever 对其进行修改。只要结果在结构上与原始模式匹配就可以了。

考虑您的情况:您使用技巧和变通方法有效破解生成的代码。与在编译之前修改模式相比,它好多少?我不认为这是更好的。它更复杂,error-prone 最后你不能说你生成的代码是你的模式的反映。实际上,您的代码没有架构。你甚至不能说你的黑客生成的代码是否充分反映了原始模式。

在编译之前修改模式非常容易。您可以轻松比较原始版本与修改版本,看看更改是否兼容。生成很简单,不需要 hack 和解决方法。


现在回答你的问题。

绑定

<annox:annotate target="field">@javax.xml.bind.annotation.XmlIDREF</annox:annotate>

我觉得不错。由于某种原因,在架构编译期间未考虑它,这就是您收到错误的原因。

很难说为什么不考虑。我会尝试以下操作:

  • 检查您在编译中是否确实 include/turn JAXB2 Basics Annotate 插件:

        <plugin>
            <groupId>org.jvnet.jaxb2.maven2</groupId>
            <artifactId>maven-jaxb2-plugin</artifactId>
            <configuration>
                <extension>true</extension>
                <args>
                    <arg>-Xannotate</arg>
                </args>
                <plugins>
                    <plugin>
                        <groupId>org.jvnet.jaxb2_commons</groupId>
                        <artifactId>jaxb2-basics-annotate</artifactId>
                    </plugin>
                </plugins>
            </configuration>
        </plugin>
    
  • 将自定义元素放在它自己的 bindings 元素中。也许由于某种原因它不能与 class 一起使用。

目前我没有看到更多应该起作用。

如果没有帮助,请在此处向我发送包含最小复制项目的 PR:

https://github.com/highsource/jaxb2-annotate-plugin-support

低于 i/idrefs。我去看看

免责声明:我是, and 的作者。