2013-10-06 107 views
0

我試圖實現所有的Java類來處理以下XML代碼片段:XML:JAXB映射Java對象和XML文檔

<party date="2012-09-30"> 
    <guest name="Albert"> 
     <drink>wine</drink> 
    </guest> 
</party> 

我已經寫了3類:

Party.java :

package li.mnet.www.java.xml; 
import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name = "party") 

public class Party { 

    @XmlAttribute(name = "date") 
    private String partyDate; 

    public Party() {} 

    public String getPartyDate() {return partyDate;} 

    public void setPartyDate(String partyDate) { 
     this.partyDate = partyDate; 
    } 
} 

Guest.java:

package li.mnet.www.java.xml; 
import javax.xml.bind.annotation.XmlElement; 

public class Guests { 
    private String name; 

    public Guests() {} 

    public void setGuestName(String name) {this.name = name;} 

    @XmlElement(name = "name") 
    public String getGuestName() {return name;} 

} 

PartyRunner.java:

package li.mnet.www.java.xml; 
import javax.xml.bind.JAXBContext; 
import javax.xml.bind.JAXBException; 
import javax.xml.bind.Marshaller; 

public class PartyRunner { 

    public static void main(String[] args) { 
     Party party = new Party(); 
     Guests guest = new Guests(); 

     party.setPartyDate("2012-09-03"); 
     guest.setGuestName("Albert"); 

     JAXBContext context; 
     try { 
      context = JAXBContext.newInstance(Party.class); 
      Marshaller m = context.createMarshaller(); 
      m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
      m.marshal(party, System.out); 
     } catch (JAXBException e) {e.printStackTrace();} 
    } 
} 

運行的應用程序後,我獲得以下控制檯輸出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<party date="2012-09-03"/> 

我有什麼改變,那類Guest.java被打印出來呢?

非常感謝您的支持!

回答

0

當你試圖通過JAXB編組一些數據時,你會給它一個你的類的實例(這裏是Party),它會遍歷你的對象及其所有屬性,並試圖序列化它們到最後輸出使用JAXB註釋提供的提示。

請記住,JAXB會忽略沒有JAXB註釋的類的屬性。您也可以告訴是否爲給定的類屬性生成XML ElementXML Attribute。您可以在屬性或它們的getter方法上使用這些註釋。

在你的例子中,你想在party元素中有一個guest元素。在main方法(PartyRunner)中,您編組Party類的實例,但此類沒有提及您的Guests類。創建一個Guests類的實例是不夠的。您必須在兩個類之間創建邏輯關係並對它們進行註釋,以便可以生成適當的XML。所以,你的Party類應該是這樣的:

import javax.xml.bind.annotation.*; 

@XmlAccessorType(XmlAccessType.FIELD) 
@XmlRootElement(name = "party") 

public class Party { 

    @XmlAttribute(name = "date") 
    private String partyDate; 

    @XmlElement(name="guest") 
    private Guests guests; 

    public Party() {} 

    public String getPartyDate() {return partyDate;} 

    public void setPartyDate(String partyDate) { 
     this.partyDate = partyDate; 
    } 

    public Guests getGuests() { 
     return guests; 
    } 

    public void setGuests(Guests guests) { 
     this.guests = guests; 
    } 
} 

如果再次運行PartyRunner你就會有這樣的事情在你的輸出:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<party> 
    <partyDate>2012-09-03</partyDate> 
    <guest> 
     <name>Albert</name> 
    </guest> 
</party> 

正如你可以看到,有一種內在的在您的guests元素中名爲name的元素。這是由於您在Guests課程中爲getGuestName方法指定的註釋。爲了讓JAXB爲此屬性(而不是XML元素)生成XML屬性,您還需要更改Guests類中的JAXB註釋。您已將getGuestName方法註釋爲@XmlElement。這將導致生成一個XML元素。如果您將其更改爲@XmlAttribute並再次運行PartyRunner,你會在你的輸出有這樣的:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<party date="2012-09-03"> 
    <guest name="Albert"/> 
</party> 
在示例XML

而且你有你的財產guestsdrink元素。 drink屬性也是如此。您的Guests類中的drink可能是String屬性,註解類型爲@XmlAttribute(name = "drink")。因此,最終的Guests類來生成你的問題的開頭提到的XML應該是這樣的:

import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlElement; 

public class Guests { 
    private String name; 
    private String drinkType; 

    public Guests(){} 

    public void setGuestName(String name) {this.name = name;} 

    @XmlAttribute(name = "name") 
    public String getGuestName() {return name;} 

    @XmlElement(name = "drink") 
    public String getDrinkType() { 
     return drinkType; 
    } 

    public void setDrinkType(String drinkType) { 
     this.drinkType = drinkType; 
    } 
} 

和你PartyRunnerdrink屬性初始化爲類似wine

public static void main(String[] args) { 
    Party party = new Party(); 
    Guests guest = new Guests(); 

    party.setPartyDate("2012-09-03"); 
    guest.setGuestName("Albert"); 
    guest.setDrinkType("wine"); 
    party.setGuests(guest); 

    JAXBContext context; 
    try { 
     context = JAXBContext.newInstance(Party.class); 
     Marshaller m = context.createMarshaller(); 
     m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
     m.marshal(party, System.out); 

    } catch (JAXBException e) {e.printStackTrace();} 
} 
+0

非常感謝您的詳細解釋,它幫助了我! – user2852537

0

我覺得黨類應該包含一個guest(客人或列表,如果你想要更多)

public class Party { 

    @XmlAttribute(name = "date") 
    private String partyDate; 
    private Guest guest; 

    public Party() {} 

    public String getPartyDate() {return partyDate;} 

    public void setPartyDate(String partyDate) { 
     this.partyDate = partyDate; 
    } 
    // getter and setter for guest 
} 

設置方對象的客人,然後元帥黨的對象。

還將名稱中的guest類中的XmlElement註釋更改爲XmlAttribute。

+0

感謝你的幫助! – user2852537