XML
The XML we will use for this example contains comments and unmapped elements. Even though we will only map the highlighted lines, this example will demonstrate how to preserve the rest of the XML document using the JAXB Binder.
<?xml version="1.0" encoding="UTF-8"?> <customer> <UNMAPPED_ELEMENT_1/> <name>Jane Doe</name> <!-- COMMENT #1 --> <address> <UNMAPPED_ELEMENT_2/> <street>1 A Street</street> <!-- COMMENT #2 --> <UNMAPPED_ELEMENT_3/> <city>Any Town</city> </address> <!-- COMMENT #3 --> <UNMAPPED_ELEMENT_4/> <phone-number type="home">555-HOME</phone-number> <!-- COMMENT #4 --> <phone-number type="cell">555-CELL</phone-number> <UNMAPPED_ELEMENT_5/> <!-- COMMENT #5 --> </customer>
Java Model
We will use the following Java model for this example. To save space the get/set methods have been omitted.
Customer
import java.util.List; import javax.xml.bind.annotation.*; @XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class Customer { private String name; private Address address; @XmlElement(name="phone-number") private List<PhoneNumber> phoneNumbers; }
Address
import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class Address { private String street; private String city; }
Phone Number
import javax.xml.bind.annotation.*; @XmlAccessorType(XmlAccessType.FIELD) public class PhoneNumber { @XmlAttribute private String type; @XmlValue private String value; }
The following code is familiar to all JAXB users. An Unmarshaller is used to load the XML into objects, and then a Marshaller is used to save the objects back to XML.
import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Customer.class); File xml = new File("input.xml"); Unmarshaller unmarshaller = jc.createUnmarshaller(); Customer customer = (Customer) unmarshaller.unmarshal(xml); customer.getAddress().setStreet("2 NEW STREET"); PhoneNumber workPhone = new PhoneNumber(); workPhone.setType("work"); workPhone.setValue("555-WORK"); customer.getPhoneNumbers().add(workPhone); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(customer, System.out); } }
<?xml version="1.0" encoding="UTF-8"?> <customer> <name>Jane Doe</name> <address> <street>2 NEW STREET</street> <city>Any Town</city> </address> <phone-number type="home">555-HOME</phone-number> <phone-number type="cell">555-CELL</phone-number> <phone-number type="work">555-WORK</phone-number> </customer>
cool
ReplyDeleteThanks a lot!
ReplyDeleteHi,
ReplyDeleteBinder is a very good thing, but when I test your sample, all comments are removed ! And idea for the issue ?
Thanks advance
This example was created with MOXy JAXB you will need to ensure that you specify the necessary jaxb.properties file. For more information see my post: JAXB - The XML Binding Standard.
ReplyDeleteThere appears to be a bug with Metro JAXB (the reference implementation) regarding the Binder.
I'm facing the same issue with the comments being omitted but the problem doesn't seem to be with JAXB. I'm at a point where I've got an instance of org.w3c.dom.Document that has comments in it (saw it using debugger)
ReplyDeletebut printing using the transformer (as your code) doesn't show the comments.
I created the document from the xml using
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setNamespaceAware(true);
// Preserve Lexical Info
dbf.setCoalescing(false);
dbf.setExpandEntityReferences(false);
dbf.setIgnoringElementContentWhitespace(false);
dbf.setIgnoringComments(false);
This made the Document keep the comments. Any idea how I can print the document WITH the comments?
Hi Enrico,
ReplyDeleteIf you are just creating a DOM with comments and using a Transformer to write the document to an OutputStream, there shouldn't be anything special you need to do. It may be a bug in the implementation of Transformer you are using.
If you are seeing the comments disappear when running the Binder example you may be using the Metro JAXB implemenation (which is included with Java SE 6), instead of the MOXy implementation. To use MOXy you will need to add the necessary jaxb.properties file. I have updated the example to include this step.
-Blaise
YES!
ReplyDeleteThank you!
My new problem is that the new element I created with java code was added to the xml with a new namespace ns0 and the root node of the new element as new attributes defining this new namespace...
But I'll figure it out ...
Thanks again!
While using a XML file under action script, the xml file is modified and I am unable to use the modified XM?
ReplyDeleteHi Silver,
ReplyDeleteIf you make changes to the XML, you can apply it back to the object model using updateJAXB on Binder.
-Blaise
Hi Doughan,
ReplyDeleteHow can append the data into existing xml file.
existing.xml
Simple text
following this example http://blogs.oracle.com/CoreJavaTechTips/entry/exchanging_data_with_xml_and1 and getting result e.g.
Simple text
Simple text
but i am expecting as,
Simple text
Simple text
I believe some relevant information from your comment was lost due to the formatting constraints of the comment section. Feel free to send me a message via my Contact Me page to start an email discussion on this issue.
ReplyDelete-Blaise
Awesome. Thanks for that!
ReplyDeleteBinder is very good for using. but i have one issue while using binder. i did the above sample and removed the value of name and run again. The empty name tag created again and again. can any one please help me? thanks in advance.
ReplyDeleteCould you log a bug for the issue you are seeing?
Delete- https://bugs.eclipse.org/bugs/enter_bug.cgi?product=EclipseLink