2017-06-22 56 views
0

我有以下的地图包含双人床或整型实例作为值,这两个扩展抽象类号码,注解如下:JAXB地图与抽象类值

@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> 

,我应该如何指定的元素可能是一个int或双任何建议我的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编辑器,这个抱怨:用我的XSD以下方法,它把同一个名字一个元素的选择中

编辑#1

@svasa建议错误:

complex type 'Settings' violates the unique particle attribution rule in its components 'value' and 'value' 

我认为这意味着下面的两个元素必须有不同的名称,他们可以两者都被命名为“价值”。

+0

由'包含一个int值和那些包含一个数字的值不能具有相同的名称'你的意思是'键'不能有'int'和'double'的同名吗? – SomeDude

+0

是的,例如key = SETTING_A值= 0.5d(double),key = SETTING_B value = 1000(和int)。 – Guillem

回答

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或intValu的元素Ë属性(但元素在这两种情况下命名):

<settings> 
    <setting name="SETTING_A" doubleValue="1.0E-5"/> 
    <setting name="SETTING_B" intValue="1000"/> 
    ... 
</settings> 

而生成的XML时有效XSD包含:

<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> 
+0

它如何解决double和int的'name'相同的问题? – SomeDude

+0

@svasa在原始问题中,我不想在我的XSD中使用不同名称的XML元素(即)。在我自己的答案中,我选择了名为的XML元素,它具有名为doubleValue和intValue的属性(在这种情况下罚款)。 – Guillem

0

xs:choice应该使您可以指定整数或双,和maxOccurs="1"将只处理一个值。

但是如果你想在key是唯一的,你可以使用XSD:唯一象下面这样:

<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> 

增加了一个​​指定你key S的关系是独特。

+0

这种解决方案给了我一个错误(请参阅原始问题**编辑#1 **),显然下的元素不能具有相同的名称(这就是为什么我已将它们命名为“double”和“int”原帖)。 – Guillem