Sometimes xml documents are very big and our requirement is to update a particular section of the document. JAXB binder comes to our help. Binder object maintains the mapping between the java object and xml infoset like DOM. Any modification to java object can be synchronized to xml held by binder object and vice versa. Below is the example
Lets have a file with below contents in result.xml
<?xml version=”1.0″ encoding=”UTF-8″ standalone=”yes”?>
<country>
<code>
<part1>1234</part1>
<part2>5678</part2>
</code>
<name>India</name>
<population>10000000</population>
</country>
and Java classes as shown below
Country
package JAXB;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Country {
private ZipCode code;
private String name;
private int population;
public ZipCode getCode() {
return code;
}
public void setCode(ZipCode code) {
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{").append("code:").append(this.code).append(",");
sb.append("name:").append(this.name).append(",");
sb.append("population:").append(this.population).append("}");
return sb.toString();
}
}
ZipCode
package JAXB;
public class ZipCode {
private int part1;
private int part2;
public int getPart1() {
return part1;
}
public void setPart1(int part1) {
this.part1 = part1;
}
public int getPart2() {
return part2;
}
public void setPart2(int part2) {
this.part2 = part2;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("{").append("part1:").append(this.part1).append(",");
sb.append("part2:").append(this.part2).append("}");
return sb.toString();
}
}
JavaBinderDemo
package JAXB;
import java.io.File;
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBContext;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
public class JAXBBinderDemo {
public static void main(String[] args) {
try
{
JAXBContext jaxbContext = JAXBContext.newInstance(Country.class);
Binder<Node> binder = jaxbContext.createBinder();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File("result.xml");
Document doc = db.parse(file);
Element documentElement = doc.getDocumentElement();
Country country = (Country)binder.unmarshal(documentElement);
ZipCode zipCode = country.getCode();
zipCode.setPart1(1111);
binder.updateXML(zipCode);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult streamResult = new StreamResult(file);
transformer.transform(source, streamResult);
}
catch(Exception excep)
{
excep.printStackTrace();
}
}
}
In the JAXBBinderDemo code we first create the JAXBContext instance and from that we get the Binder object. I will use DOM to maintain the xml infoset. So the parameterized type for Binder is Node.
Binder<Node> binder
Get the DOM object of the xml as shown below
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
DocumentBuilder db = dbf.newDocumentBuilder();
File file = new File(“result.xml”);
Document doc = db.parse(file);
Element documentElement = doc.getDocumentElement();
Convert the xml infoset to java object using Binder’s unmarshal method
Country country = (Country)binder.unmarshal(documentElement);
The above code unmarshal and return the country object and the binder object maps the java object with xml infoset.
Next we update the zip code of the country object
ZipCode zipCode = country.getCode();
zipCode.setPart1(1111);
Now the update in java object has to be replicated in the DOM object to keep the xml updated, which is done using updateXML method
binder.updateXML(zipCode);
Next we save the DOM object.
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult streamResult = new StreamResult(file);
transformer.transform(source, streamResult);