2017-06-22 54 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