我有以下Map包含Double或Integer实例作为值,两者都扩展了抽象类Number,注释如下:
@XmlElement(name="settings")
private Map<String,Number> settings;
它被编组为XML:
<settings>
<entry>
<key>SETTING_A</key>
<value xsi:type="xs:double">0.03</value>
</entry>
<entry>
<key>SETTING_B</key>
<value xsi:type="xs:int">1000</value>
</entry>
</settings>
我还需要为这种类型的XML提供XSD,这是我遇到问题的地方。我试图用一个选项定义一个complexType,但不起作用,因为包含int的元素和包含double的元素不能具有相同的名称(即它们不能同时命名为“value” ),这正是JAXB生成的XML所做的。
以下XSD可以使用,但我不想使用不同的元素名称(或):
<xsd:complexType name="Entry">
<xsd:sequence>
<xsd:element name="key" type="NimrodSettingKey" minOccurs="1" maxOccurs="1"/>
<xsd:choice>
<xsd:element name="double" type="xsd:double" minOccurs="1" maxOccurs="1"/>
<xsd:element name="int" type="xsd:integer" minOccurs="1" maxOccurs="1"/>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
有关如何在XSD文档中指定元素可以是int还是double的任何建议?
谢谢!
编辑#1
@svasa建议在我的XSD中使用以下方法,它为选择中的元素赋予相同的名称:
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsd:element name="Settings"/>
<xsd:complexType name="Settings">
<xsd:sequence>
<xsd:element name="key" type="xsd:string" minOccurs="1" maxOccurs="1" />
<xsd:choice>
<xsd:element name="value" xs:type="xsi:double" minOccurs="1" maxOccurs="1" />
<xsd:element name="value" xs:type="xsi:integer" minOccurs="1" maxOccurs="1" />
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:schema>
但是我的XSD编辑抱怨这个错误:
complex type 'Settings' violates the unique particle attribution rule in its components 'value' and 'value'
我认为这意味着每个下面的两个元素必须有不同的名称,它们不能都被命名为“value”。
答案 0 :(得分:0)
我终于选择了重构我的代码:
@XmlElement(name="settings")
private Map<String,Number> settings
为:
@XmlElementWrapper(name="settings")
@XmlElement(name="setting")
private List<Setting> settings;
我的设置类已重命名为“设置”,现在存储一个具有属性的设置:
@XmlAttribute(name="name")
private String name;
@XmlAttribute(name="intValue")
private Integer intValue;
@XmlAttribute(name="doubleValue")
private Double doubleValue;
当编组为XML时,它会生成具有doubleValue或intValue属性的元素(但在这两种情况下都会命名该元素):
<settings>
<setting name="SETTING_A" doubleValue="1.0E-5"/>
<setting name="SETTING_B" intValue="1000"/>
...
</settings>
当XSD包含:
时,生成的XML有效<xsd:complexType name="Settings">
<xsd:sequence>
<xsd:element name="setting" type="Setting" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="Setting">
<xsd:attribute name="name" type="xsd:string"/>
<xsd:attribute name="doubleValue" type="xsd:double"/>
<xsd:attribute name="intValue" type="xsd:int"/>
</xsd:complexType>
答案 1 :(得分:0)
xs:choice
应该可以指定整数或双精度,maxOccurs="1"
只会处理一个值。
但是如果你希望key
是唯一的,你可以使用xsd:unique,如下所示:
<xsd:element name="settings">
<xsd:complexType>
<xsd:sequence>
<xsd:element maxOccurs="unbounded" name="entry">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="key" type="NimrodSettingKey" minOccurs="1" maxOccurs="1" />
<xsd:choice>
<xsd:element name="value" xsi:type="xsd:double" minOccurs="1" maxOccurs="1" />
<xsd:element name="value" xsi:type="xsd:integer" minOccurs="1" maxOccurs="1" />
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:unique name="keyU">
<xsd:selector xpath=".//key" />
<xsd:field xpath="." />
</xsd:unique>
</xsd:element>
本节:
<xsd:unique name="keyU">
<xsd:selector xpath=".//key" />
<xsd:field xpath="." />
</xsd:unique>
添加unique constraint,指明您的key
应该是唯一的。