XML:JAXB映射Java对象和XML文档

时间:2013-10-06 20:27:17

标签: java android 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类也被打印出来了?

非常感谢您的支持!

2 个答案:

答案 0 :(得分:0)

我认为派对类应该包含一个访客(如果你想要更多的话,还应该包含访客列表)

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
}

设置派对对象的访客然后封送派对对象。

同时将名称中的XmlElement注释更改为guest别墅类中的XmlAttribute。

答案 1 :(得分:0)

当你试图通过JAXB封送一些数据时,你会给它一个你的类的实例(这里是Party),它将遍历你的对象及其所有属性,并尝试将它们序列化为最终输出使用JAXB注释提供的提示。

请记住,JAXB忽略没有JAXB注释的类的属性。您还可以告诉它是否为给定的类属性生成XML ElementXML Attribute。您可以在属性或其getter方法上使用这些注释。

在您的示例中,您希望guest元素中包含party元素。在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>

如您所见,name元素中有一个名为guests的内部元素。这是因为您在getGuestName课程中为Guests方法指定了注释。为了使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中,drink属性中包含guests元素。 drink属性也是如此。 drinkString可以是Guests类中的@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; } } 类应该是这样的:

PartyRunner

并且您的drink应将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();} } 的内容:

{{1}}