gpt4 book ai didi

java - JAXB,如何为具有元素重复属性的模式生成类

转载 作者:行者123 更新时间:2023-11-30 07:13:32 25 4
gpt4 key购买 nike

我有一个架构,即 a schema for metalink file 。我想使用 Maven maven-jaxb2-plugin 生成类。

此架构允许输入版本作为属性或元素,因此它具有重复的属性。如何使用 Jaxb 为此类模式生成 Java 类(甚至可能),而不重命名属性或元素。所以基本上我希望这个重复的属性映射到某种复杂类型,并带有内部指示它是属性还是元素。至少在我看来,这样的解决方案是最接近的 XML 表示。

这样的事情可以实现吗?如果是,那么如何?

下面是有问题的 xsd 片段。

<xs:complexType name="metalinkType">
<xs:all>
<xs:element minOccurs="0" name="description" type="xs:string"/>
<xs:element minOccurs="0" name="identity" type="xs:string"/>
<xs:element minOccurs="0" name="license" type="licenseType"/>
<xs:element minOccurs="0" name="publisher" type="publisherType"/>
<xs:element minOccurs="0" name="releasedate" type="RFC822DateTime"/>
<xs:element minOccurs="0" name="tags" type="xs:string"/>
<xs:element minOccurs="0" name="version" type="xs:string"/>
<xs:element name="files" type="filesType"/>
</xs:all>
<xs:attribute name="version" type="xs:string" default="3.0"/>
<xs:attribute name="origin" type="xs:anyURI"/>
<xs:attribute name="type" default="static">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="dynamic"/>
<xs:enumeration value="static"/>
</xs:restriction>
</xs:simpleType>
</xs:attribute>
<xs:attribute name="pubdate" type="RFC822DateTime"/>
<xs:attribute name="refreshdate" type="RFC822DateTime"/>
<xs:attribute name="generator" type="xs:string"/>
</xs:complexType>

编辑:

对于这样的模式,我希望由 Jaxb 生成一个 Java 模型,例如:

public class Metalink {
private PropertyType<String> version;
...
}

public class PropertyType<T> {
private T val;
private boolean isAttribute;
...
}

是否有可能实现这样的目标,或者是在 Java 模型中拥有两个不同属性的唯一解决方案?

最佳答案

是的,可以通过JAXB Binding Customization来完成.

这是我为解决您的问题而制作的一个小 XSD(属性和元素之间的名称冲突):

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://hello"
elementFormDefault="qualified"
xmlns:tns="http://hello"
>
<xs:element name="metalink" type="tns:metalinkType" />
<xs:complexType name="metalinkType">
<xs:sequence>
<xs:element name="version" type="xs:string" minOccurs="1" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required" />
</xs:complexType>
</xs:schema>

eclipse 执行 JAXB Generation 时,出现如下错误:

[ERROR] Property "Version" is already defined. Use <jaxb:property> to resolve this conflict

但是,当我使用一些自定义标签修改 XSD 时,问题就消失了:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://hello"
elementFormDefault="qualified"
xmlns:tns="http://hello"
xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" <!-- ADDED -->
jaxb:version="1.0" <!-- ADDED -->
>
<xs:element name="metalink" type="tns:metalinkType" />
<xs:complexType name="metalinkType">
<xs:sequence>
<xs:element name="version" type="xs:string" minOccurs="1" />
</xs:sequence>
<xs:attribute name="version" type="xs:string" use="required" >
<xs:annotation>
<xs:appinfo>
<jaxb:property name="version2"/> <!-- ADDED! -->
</xs:appinfo>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:schema>

避免冲突问题并允许生成关联的类。

注意:所提供的示例假设您希望(并且您可以)使用内联自定义修改有问题的 XSD...根据文档,您还可以在外部文件中定义自定义(您需要检查并尝试这个)。

this是另一个感兴趣的链接...

希望这有帮助!

** 更新 **:实现您想要的 Java 模型的示例。该示例假设您遵循之前描述的步骤...您将以这样的类结束:

// xml annotations
public class MetalinkType {
...
@XmlElement(name = "version)
private String version;
...
@XmlAttribute(name = "version")
private String version2;
...
public void setVersion(String version, boolean asElem) {
If (asElem) {
this.version = version;
} else {
this.version2 = version;
}
}
// individual setter as setVersion and setVersion2 are not exposed
}

关于java - JAXB,如何为具有元素重复属性的模式生成类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38788440/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com