JAXB is a powerful yet simple to use api to read and write xml in java .
This is the sample xml which we want to read using java .
this is root class which is mapped to xmlObject element in the xml
This is the sample xml which we want to read using java .
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <xmlObject> <auction> <auctionType>PUBLIC</auctionType> <description>this is auction from file</description> <product> <details>Product XML</details> <name>this is product from file</name> </product> <bids> <bid> <amount>23</amount> <time>23-12-2012</time> <user>abhishek</user> </bid> <bid> <amount>25</amount> <time>23-11-2012</time> <user>john</user> </bid> </bids> <startDateTime>2012-10-30T23:46:13.394</startDateTime> <endDateTime>2012-12-30T23:46:13.394</endDateTime> </auction> </xmlObject>
this is root class which is mapped to xmlObject element in the xml
package com.xml; import java.io.File; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.bind.annotation.XmlRootElement; import com.model.Auction; import com.model.AuctionStatus; import com.model.AuctionType; import com.model.Bid; import com.model.Product; /** * JAXB class to create Java Objects from XML File * @author abhishek.somani * */ @XmlRootElement(name = "xmlObject") public class XMLObject { private List<auction> auction; public XMLObject() { auction = new ArrayList<auction>(); } public List<auction> getAuction() { return auction; } public List<auction> setAuction(List<auction> aunctions) { return this.auction = aunctions; } }
This is Auction class which is mapped to auction element in xml.
package com.model; import java.io.Serializable; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; /** * Model class Mapped to database table auction and XmlElement auction * @author abhishek.somani * */ @XmlRootElement public class Auction implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Product product; private int id; private String auctionStatus; private String auctionType; private String description; private Date startDateTime; private Date endDateTime; private Bid winnerBid; private Set<Bid> bids = new HashSet<Bid>(); public static long getSerialversionuid() { return serialVersionUID; } public Bid getWinnerBid() { return winnerBid; } public void setWinnerBid(Bid winnerbid) { this.winnerBid = winnerbid; } public Auction() { } public Auction(Product product, Date startTime, String type, String status) { this.product = product; this.startDateTime = startTime; this.auctionType = type; this.auctionStatus = status; } public Set<Bid> getBids() { return bids; } @XmlElement(name = "bid") @XmlElementWrapper(name = "bids") public void setBids(Set<Bid> bids) { this.bids = bids; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } public int getId() { return id; } @XmlTransient public void setId(int id) { this.id = id; } public String getAuctionStatus() { return auctionStatus; } public void setAuctionStatus(String auctionStatus) { this.auctionStatus = auctionStatus; } public String getAuctionType() { return auctionType; } public void setAuctionType(String acutionType) { this.auctionType = acutionType; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Date getStartDateTime() { return startDateTime; } public void setStartDateTime(Date startDateTime) { this.startDateTime = startDateTime; } public Date getEndDateTime() { return endDateTime; } public void setEndDateTime(Date endDateTime) { this.endDateTime = endDateTime; } public boolean isActive() { return this.auctionStatus.equals(AuctionStatus.ACTIVE.toString()); } }@XmlElementWrapper is used to create a list object containing the inner JAXB elements . like in xml bids element contains zero or more bid element , where bid also can be mapped to another JAXB class . By default if you don't specify @XmlElement on every getter method , it map every member field to xml. @XmlTransient is used if we want to skip some fields not to be mapped in xml . Bid class which is mapped to bid element in xml.
package com.model; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; /** * Model class for bid table * @author abhishek.somani * */ @XmlRootElement public class Bid implements ComparableProduct class which is mapped to product element in xml.{ private int id; private String user; private Auction auction; private double amount; private Date time; private Set auctions = new HashSet(0); public Bid() { } public Bid(Auction auction, String user, double amount, Date time) { this.auction = auction; this.user = user; this.amount = amount; this.time = time; } public int getId() { return id; } @XmlTransient public void setId(int id) { this.id = id; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } public Auction getAuction() { return auction; } public void setAuction(Auction auction) { this.auction = auction; } public Double getAmount() { return amount; } public void setAmount(Double amount) { this.amount = amount; } public Date getTime() { return time; } public void setTime(Date time) { this.time = time; } //compareto method determines which bid is higher @Override public int compareTo(Bid o) { int compare = 0; if (this.amount > o.amount) compare = 1; else if (this.amount < o.amount) compare = -1; else if (this.amount == o.amount) { //if amount is same then compare time , bid with more time is smaller compare = this.time.compareTo(o.time) >= 0 ? -1 : 1; } return compare; } public Set getAuctions() { return this.auctions; } public void setAuctions(Set auctions) { this.auctions = auctions; } }
package com.model; import java.util.HashSet; import java.util.Set; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement public class Product { private int id; private String name; private String details; private Set auctions = new HashSet(0); public Product() { } public Product(String name, String details) { this.name = name; this.details = details; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDetails() { return details; } public void setDetails(String details) { this.details = details; } public Set getAuctions() { return this.auctions; } public void setAuctions(Set auctions) { this.auctions = auctions; } }
Main class to read and write
public static void main(String args[]) throws JAXBException { new XMLObject().writeXml(null, null); } public ListCommon Exception : JAXBException :Class has two properties of the same name To resolve this error , we have to use annotations on getter method rather than field methodsreadXml(File file) throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); XMLObject a = (XMLObject) jaxbUnmarshaller.unmarshal(file); for (Auction au : a.getAuction()) { au.setAuctionStatus(AuctionStatus.ACTIVE.name()); au.setEndDateTime(null); } return null; } public List readXml(InputStream is) throws JAXBException { JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); XMLObject a = (XMLObject) jaxbUnmarshaller.unmarshal(is); return a.getAuction(); } public void writeXml(List list,File f) throws JAXBException { XMLObject root = new XMLObject(); List auctions = new LinkedList (); Auction a = new Auction(); a.setAuctionType(AuctionType.PUBLIC.toString()); a.setDescription("test"); Set bids = new HashSet (); Bid b = new Bid(); b.setAmount(new Double(233)); b.setTime(new Date()); bids.add(b); a.setBids(bids); Product p = new Product(); p.setName("p1"); p.setDetails("details"); a.setProduct(p); a.setStartDateTime(new Date()); auctions.add(a); root.setAuction(auctions); File file = new File("F:/Workspace/testing/wfile.xml"); JAXBContext jaxbContext = JAXBContext.newInstance(XMLObject.class); Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); // output pretty printed jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); jaxbMarshaller.marshal(root, file); jaxbMarshaller.marshal(root, System.out); }