JAXB XML Prefix Issue - jaxb

I have an input xml file of below one.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<cxp:exportedDefect xmlns:cxp="http://export.coverity.com/v7">
<user>admin</user>
<project>tev</project>
<timeStamp>2014-05-23T08:45:08.916+03:00</timeStamp>
<cxp:mergedDefect>
<checkerName>FORWARD_NULL</checkerName>
<checkerSubcategory>deref_constant_null</checkerSubcategory>
<cid>10549</cid>
<componentName>Default.Other</componentName>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>DefectStatus</name>
</attributeDefinitionId>
<attributeValueId>
<name>Dismissed</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Classification</name>
</attributeDefinitionId>
<attributeValueId>
<name>False Positive</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Action</name>
</attributeDefinitionId>
<attributeValueId>
<name>Undecided</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Severity</name>
</attributeDefinitionId>
<attributeValueId>
<name>Unspecified</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Fix Target</name>
</attributeDefinitionId>
<attributeValueId>
<name>Untargeted</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Legacy</name>
</attributeDefinitionId>
<attributeValueId>
<name>False</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Owner</name>
</attributeDefinitionId>
<attributeValueId>
<name>Unassigned</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>TranslatedOwner</name>
</attributeDefinitionId>
<attributeValueId>
<name>Unassigned</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>OwnerName</name>
</attributeDefinitionId>
<attributeValueId>
<name>etevgul</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Comment</name>
</attributeDefinitionId>
<attributeValueId>
<name></name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>ExternalReference</name>
</attributeDefinitionId>
<attributeValueId>
<name></name>
</attributeValueId>
</defectStateAttributeValues>
<domain>STATIC_JAVA</domain>
<filePathname>/user/user-service-impl/src/main/java/com/ericsson/enk/imcp/core/user/service/impl/UserServiceImpl.java</filePathname>
<firstDetected>2014-04-07T13:47:03.730+03:00</firstDetected>
<firstDetectedSnapshotId>10014</firstDetectedSnapshotId>
<functionDisplayName>com.ericsson.enk.imcp.core.user.service.impl.UserServiceImpl.authenticate(com.ericsson.enk.imcp.core.common.domain.Email, java.lang.String)</functionDisplayName>
<lastDetected>2014-05-12T17:06:44.339+03:00</lastDetected>
<lastDetectedSnapshotId>10020</lastDetectedSnapshotId>
<lastFixed>2014-05-09T17:15:27.543+03:00</lastFixed>
<lastTriaged>2014-04-24T16:21:17.912+03:00</lastTriaged>
<mergeKey>e4a7c34660b74135e992f11cdfc5b16d</mergeKey>
<occurrenceCount>1</occurrenceCount>
</cxp:mergedDefect>
<latestSnapshotId>10020</latestSnapshotId>
<streamDefects>
<cxp:streamDefect>
<checkerSubcategoryId>
<checkerName>FORWARD_NULL</checkerName>
<domain>STATIC_JAVA</domain>
<subcategory>deref_constant_null</subcategory>
</checkerSubcategoryId>
<cid>10549</cid>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>DefectStatus</name>
</attributeDefinitionId>
<attributeValueId>
<name>Dismissed</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Classification</name>
</attributeDefinitionId>
<attributeValueId>
<name>False Positive</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Action</name>
</attributeDefinitionId>
<attributeValueId>
<name>Undecided</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Fix Target</name>
</attributeDefinitionId>
<attributeValueId>
<name>Untargeted</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Severity</name>
</attributeDefinitionId>
<attributeValueId>
<name>Unspecified</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Legacy</name>
</attributeDefinitionId>
<attributeValueId>
<name>False</name>
</attributeValueId>
</defectStateAttributeValues>
<defectStateAttributeValues>
<attributeDefinitionId>
<name>Comment</name>
</attributeDefinitionId>
<attributeValueId>
<name></name>
</attributeValueId>
</defectStateAttributeValues>
<id>
<defectTriageId>10345</defectTriageId>
<defectTriageVerNum>1</defectTriageVerNum>
<id>21194</id>
<verNum>2</verNum>
</id>
<streamId>
<name>IMCP_V3-java</name>
</streamId>
</cxp:streamDefect>
</streamDefects>
<cxp:checkerProperties>
<subcategoryShortDescription>Explicit null dereferenced</subcategoryShortDescription>
</cxp:checkerProperties>
</cxp:exportedDefect>
As you can see some of them contains namespace frefix and some of them not. I tried to model the xml to pojo to unmurshall but. I couldn't make it to set inner prefixed objects mapped.
Somehow I am thinking of the inner prefixes are being discarded by jaxb.
My root xml element is :
package com.ericsson.integration.jira.jaxb.model;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
import java.io.Serializable;
import java.util.*;
/**
* Created by olgunkaya on 11.09.2014.
*/
#XmlRootElement (name = "exportedDefect", namespace = "http://export.coverity.com/v7")
public class CoverityDefect implements Serializable {
private String user;
private String project;
private Date timeStamp;
private MergedDefect mergedDefect;
private String latestSnapshotId;
private StreamDefects streamDefects;
private CheckerProperties checkerProperties;
public Date getTimeStamp() {
return timeStamp;
}
#XmlElement
public void setTimeStamp(Date timeStamp) {
this.timeStamp = timeStamp;
}
public String getUser() {
return user;
}
#XmlElement
public void setUser(String user) {
this.user = user;
}
public String getProject() {
return project;
}
#XmlElement
public void setProject(String project) {
this.project = project;
}
public MergedDefect getMergedDefect() {
return mergedDefect;
}
#XmlElement
public void setMergedDefect(MergedDefect mergedDefect) {
this.mergedDefect = mergedDefect;
}
public String getLatestSnapshotId() {
return latestSnapshotId;
}
#XmlElement
public void setLatestSnapshotId(String latestSnapshotId) {
this.latestSnapshotId = latestSnapshotId;
}
public StreamDefects getStreamDefects() {
return streamDefects;
}
#XmlElement
public void setStreamDefects(StreamDefects streamDefects) {
this.streamDefects = streamDefects;
}
public CheckerProperties getCheckerProperties() {
return checkerProperties;
}
#XmlElement
public void setCheckerProperties(CheckerProperties checkerProperties) {
this.checkerProperties = checkerProperties;
}
}
And one of the failing element is mergedDefect in the xml with the model of :
package com.ericsson.integration.jira.jaxb.model;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* Created by olgunkaya on 11.09.2014.
*/
public class MergedDefect implements Serializable{
private String checkerName;
private String checkerSubcategory;
private String cid;
private String componentName;
private List<DefectStateAttributeValues> defectStateAttributeValues;
private String domain;
private String filePathname;
private Date firstDetected;
private String firstDetectedSnapshotId;
private String functionDisplayName;
private Date lastDetected;
private String lastDetectedSnapshotId;
private Date lastFixed;
private Date lastTriaged;
private String mergeKey;
private String occurrenceCount;
public String getCheckerName() {
return checkerName;
}
#XmlElement
public void setCheckerName(String checkerName) {
this.checkerName = checkerName;
}
public String getCheckerSubcategory() {
return checkerSubcategory;
}
#XmlElement
public void setCheckerSubcategory(String checkerSubcategory) {
this.checkerSubcategory = checkerSubcategory;
}
public String getCid() {
return cid;
}
#XmlElement
public void setCid(String cid) {
this.cid = cid;
}
public String getComponentName() {
return componentName;
}
#XmlElement
public void setComponentName(String componentName) {
this.componentName = componentName;
}
public List<DefectStateAttributeValues> getDefectStateAttributeValues() {
return defectStateAttributeValues;
}
#XmlElement
public void setDefectStateAttributeValues(List<DefectStateAttributeValues> defectStateAttributeValues) {
this.defectStateAttributeValues = defectStateAttributeValues;
}
public String getDomain() {
return domain;
}
#XmlElement
public void setDomain(String domain) {
this.domain = domain;
}
public String getFilePathname() {
return filePathname;
}
#XmlElement
public void setFilePathname(String filePathname) {
this.filePathname = filePathname;
}
public Date getFirstDetected() {
return firstDetected;
}
#XmlElement
public void setFirstDetected(Date firstDetected) {
this.firstDetected = firstDetected;
}
public String getFirstDetectedSnapshotId() {
return firstDetectedSnapshotId;
}
#XmlElement
public void setFirstDetectedSnapshotId(String firstDetectedSnapshotId) {
this.firstDetectedSnapshotId = firstDetectedSnapshotId;
}
public String getFunctionDisplayName() {
return functionDisplayName;
}
#XmlElement
public void setFunctionDisplayName(String functionDisplayName) {
this.functionDisplayName = functionDisplayName;
}
public Date getLastDetected() {
return lastDetected;
}
#XmlElement
public void setLastDetected(Date lastDetected) {
this.lastDetected = lastDetected;
}
public String getLastDetectedSnapshotId() {
return lastDetectedSnapshotId;
}
#XmlElement
public void setLastDetectedSnapshotId(String lastDetectedSnapshotId) {
this.lastDetectedSnapshotId = lastDetectedSnapshotId;
}
public Date getLastFixed() {
return lastFixed;
}
#XmlElement
public void setLastFixed(Date lastFixed) {
this.lastFixed = lastFixed;
}
public Date getLastTriaged() {
return lastTriaged;
}
#XmlElement
public void setLastTriaged(Date lastTriaged) {
this.lastTriaged = lastTriaged;
}
public String getMergeKey() {
return mergeKey;
}
#XmlElement
public void setMergeKey(String mergeKey) {
this.mergeKey = mergeKey;
}
public String getOccurrenceCount() {
return occurrenceCount;
}
#XmlElement
public void setOccurrenceCount(String occurrenceCount) {
this.occurrenceCount = occurrenceCount;
}
}
Above mergedDefect object always returns null.
I am using below piece for testing.
System.out.println("Creating object from XML");
File file = new File("/Users/olgunkaya/Downloads/atlassian-jira-rest-java-client-890e21ab0a7b/" +
"jira-integration/resources/cov-export5653165670998483522.xml");
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
CoverityDefect coverityDefectt = (CoverityDefect) jaxbUnmarshaller.unmarshal(file);
System.out.println(coverityDefectt);

Thanks to an old answer on this post.
How to make JAXB unmarshaller to ignore prefixes?
I have used the same way to remove all prefixes. And now it's working.
Simply to solve such problems. One can extend XMLFilterImpl and Override startElement and endElement methods. Then you can modify the qName parameters passed to this method. Implementation may vary depending on what you need.
you should also be careful with the POJOs to be used to map the xml to. You may have some Sax Exceptions.
In that case you may need to play around with the xmlfilter implementation a bit.

Related

If a class has #XmlElement property, it cannot have #XmlValue property error

I am getting below exception when I am trying to marshel below java classes to below expected xml.
Exception:
If a class has #XmlElement property, it cannot have #XmlValue property.
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parent>
I am the parent element of mixedtype.
<child>I am the child element</child>
</parent>
Parent.java
#XmlRootElement(name = "parent")
public class Parent{
protected List<Child> child= new ArrayList<Child>();
protected List<String> text= new ArrayList<String>();
#XmlElementRef(name="child",type=Child.class)
public List<Child> getChild() {
return child;
}
#XmlMixed
public List<String> getText() {
return text;
}
public void setChild(Child value) {
this.child.add(value);
}
public void setText(String value) {
this.text.add(value);
}
}
Child.java
public class Child {
#XmlValue
protected String value;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
For the above the XML I tried this and seems to work fine for me:
XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<parent>
I am the parent element of mixedtype.
<child>I am the child element</child>
</parent>
Parent.class:
#XmlRootElement(name = "parent")
#Data
#NoArgsConstructor
#XmlAccessorType(XmlAccessType.FIELD)
public class Parent {
#XmlMixed
#XmlAnyElement
private List<Object> textContent;
#XmlElement(name = "child")
private String child;
}
My Main class:
public class JaxbExampleMain {
public static void main(String[] args) throws JAXBException, XMLStreamException {
final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("parent.xml");
final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
final Unmarshaller unmarshaller = JAXBContext.newInstance(Parent.class).createUnmarshaller();
final Parent parent = unmarshaller.unmarshal(xmlStreamReader, Parent.class).getValue();
System.out.println(parent.toString());
Marshaller marshaller = JAXBContext.newInstance(Parent.class).createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
marshaller.marshal(parent, System.out);
}
}
Following is the output that I am getting:
Parent(textContent=[
I am the parent element of mixedtype.
,
], child=I am the child element)
<parent>
I am the parent element of mixedtype.
<child>I am the child element</child>
</parent>

Create xml string for java jaxb bean with Root class & inner classes having different name spaces

I have a Root Class called Employee, which has two elements empid and name and another jaxb class called Address. Below is the sample snippet.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Request",propOrder = {
"header",
"body",
"signature"
})
#XmlRootElement(name="Employee")
public class Employee
implements Serializable
{
#XmlElement(name = "Header", required = true)
protected String empId;
#XmlElement(name = "Body", required = true)
protected String empName;
#XmlElement(name = "Address", required = true)
protected Address address;
.. setters and getters
}
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Address", propOrder = {
"streetLine1",
"streetLine2",
})
#XmlRootElement(name="Address",namespace= "http://www.w3.org/2000/09/xmldsig#")
public class Employee
implements Serializable
{
private final static long serialVersionUID = 100L;
#XmlElement(name = "addressLine1", required = true)
protected String addressLine1;
#XmlElement(name = "addressLine2", required = true)
protected String addressLine2;
//Setters and getters
}
Now when I generate the XML string with jaxb marshalling I want the expected result like this:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Employee xmlns="http://www.test.com">
<empId>124</empId>
<empName>name</empName>
<Address xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<ns2:streetLine1 Id="line1"/>
<ns2:streetLine2 Id="Line2"/>
</Address>
</Request>
Please suggest. Thanks in Advance.
There are some problems with your JAXB classes, I think you have copy pasted and changed some names wrongly. The following elements inside #XMLType must be defined as #XMLElement.
#XmlType(name = "Request",propOrder = {
"header",
"body",
"signature"
})
Anyways assuming the classes are right. You will need 2 changes to generate XML that has elements referred in different namespace.
Move the namespace to package level using #XMLSchema. i.e Add package-info.java at the package level to specify the namespaces.
Provide Address element with its own namespace in Employee class. Each element if not in parent namespace, must be overridden at this level.
package-info.java
#XmlSchema(
namespace = "http://www.test.com",
elementFormDefault = XmlNsForm.QUALIFIED)
package int1.d;
import javax.xml.bind.annotation.*;
Employee.java
package int1.d;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Request",propOrder = {
"header",
"body",
"signature"
})
#XmlRootElement(name="Employee")
public class Employee
implements Serializable
{
private static final long serialVersionUID = 8293193254658211943L;
#XmlElement(name = "Header", required = true)
protected String empId;
#XmlElement(name = "Body", required = true)
protected String empName;
#XmlElement(name = "Address", namespace="http://www.w3.org/2000/09/xmldsig#", required = true )
protected Address address;
public String getEmpId() {
return empId;
}
public void setEmpId(String empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
package-info.java
#XmlSchema(
namespace = "http://www.w3.org/2000/09/xmldsig#",
elementFormDefault=XmlNsForm.QUALIFIED )
package int1.d2;
import javax.xml.bind.annotation.*;
Address.java
package int1.d2;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Address", propOrder = {
"streetLine1",
"streetLine2",
})
#XmlRootElement(name="Address")
public class Address
implements Serializable
{
private final static long serialVersionUID = 100L;
#XmlElement(name = "addressLine1", required = true)
protected String addressLine1;
#XmlElement(name = "addressLine2", required = true)
protected String addressLine2;
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
}
output generated by JAXB
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Employee xmlns="http://www.test.com" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#">
<Header>124</Header>
<Body>bae</Body>
<ns2:Address>
<ns2:addressLine1>line1</ns2:addressLine1>
<ns2:addressLine2>line2</ns2:addressLine2>
</ns2:Address>
</Employee>

NPE when marshalling/unmarshalling JAXBElement

I have following JAXB-mapped class:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "date_or_period_t", propOrder = {
"date", "beginDate", "endDate"
})
public class DateOrPeriodT
implements Serializable
{
private final static long serialVersionUID = 1L;
#XmlElementRef(name = "date", type = JAXBElement.class, required = false)
protected JAXBElement<DateOrDatetimeT> date;
#XmlElementRef(name = "begin_date", type = JAXBElement.class, required = false)
protected JAXBElement<Date> beginDate;
#XmlElementRef(name = "end_date", type = JAXBElement.class, required = false)
protected JAXBElement<Date> endDate;
public JAXBElement<DateOrDatetimeT> getDate() { return date; }
public void setDate(JAXBElement<DateOrDatetimeT> value) { this.date = value; }
public JAXBElement<Date> getBeginDate() { return beginDate; }
public void setBeginDate(JAXBElement<Date> value) { this.beginDate = value; }
public JAXBElement<Date> getEndDate() { return endDate; }
public void setEndDate(JAXBElement<Date> value) { this.endDate = value; }
}
and corresponding xsd:
<xsd:complexType name="date_or_period_t">
<xsd:choice minOccurs="0">
<xsd:element name="date" type="date_or_datetime_t" nillable="true"></xsd:element>
<xsd:sequence>
<xsd:element name="begin_date" type="xsd:date" nillable="true"></xsd:element>
<xsd:element name="end_date" type="xsd:date" nillable="true"></xsd:element>
</xsd:sequence>
</xsd:choice>
</xsd:complexType>
When one or both end_date, begin_date is set to xsi:nil="true", MOXy throws NPE:
Caused by: java.lang.NullPointerException
at org.eclipse.persistence.internal.jaxb.XMLJavaTypeConverter.convertDataValueToObjectValue(XMLJavaTypeConverter.java:155)
at org.eclipse.persistence.oxm.mappings.converters.XMLConverterAdapter.convertDataValueToObjectValue(XMLConverterAdapter.java:28)
at org.eclipse.persistence.oxm.mappings.converters.XMLConverterAdapter.convertDataValueToObjectValue(XMLConverterAdapter.java:1)
at org.eclipse.persistence.internal.jaxb.JAXBElementConverter.convertDataValueToObjectValue(JAXBElementConverter.java:78)
at org.eclipse.persistence.internal.jaxb.JAXBElementConverter.convertDataValueToObjectValue(JAXBElementConverter.java:56)
at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.convertDataValueToObjectValue(XMLDirectMapping.java:526)
at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getAttributeValue(XMLDirectMapping.java:296)
at org.eclipse.persistence.oxm.mappings.XMLDirectMapping.getAttributeValue(XMLDirectMapping.java:1)
at org.eclipse.persistence.internal.oxm.XMLDirectMappingNodeValue.endElement(XMLDirectMappingNodeValue.java:165)
at org.eclipse.persistence.internal.oxm.XMLChoiceObjectMappingNodeValue.endElement(XMLChoiceObjectMappingNodeValue.java:177)
at org.eclipse.persistence.internal.oxm.record.UnmarshalRecordImpl.endElement(UnmarshalRecordImpl.java:1050)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parseEvent(XMLStreamReaderReader.java:154)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:99)
at org.eclipse.persistence.internal.oxm.record.XMLStreamReaderReader.parse(XMLStreamReaderReader.java:86)
at org.eclipse.persistence.internal.oxm.record.SAXUnmarshaller.unmarshal(SAXUnmarshaller.java:895)
at org.eclipse.persistence.oxm.XMLUnmarshaller.unmarshal(XMLUnmarshaller.java:659)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:585)
at org.eclipse.persistence.jaxb.JAXBUnmarshaller.unmarshal(JAXBUnmarshaller.java:140)
When date is xsi:nil it works fine, when both begin_date and end_date is not xsi:nil it's fine.
#XmlElementDecl(namespace = "", name = "date", scope = DateOrPeriodT.class)
public JAXBElement<DateOrDatetimeT> createDateOrPeriodTDate(DateOrDatetimeT value) {
return new JAXBElement<DateOrDatetimeT>(_DateOrPeriodTDate_QNAME, DateOrDatetimeT.class, DateOrPeriodT.class, value);
}
#XmlElementDecl(namespace = "", name = "begin_date", scope = DateOrPeriodT.class)
#XmlJavaTypeAdapter(AdapterDate.class)
public JAXBElement<Date> createDateOrPeriodTBeginDate(Date value) {
return new JAXBElement<Date>(_DateOrPeriodTBeginDate_QNAME, Date.class, DateOrPeriodT.class, value);
}
#XmlElementDecl(namespace = "", name = "end_date", scope = DateOrPeriodT.class)
#XmlJavaTypeAdapter(AdapterDate.class)
public JAXBElement<Date> createDateOrPeriodTEndDate(Date value) {
return new JAXBElement<Date>(_DateOrPeriodTEndDate_QNAME, Date.class, DateOrPeriodT.class, value);
When I use the following setup, everything works fine.
class DateOrDatetimeT ->
package org.eclipse.persistence.testing.jaxb.aso.np;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "date", propOrder = {
"date"
})
public class DateOrDatetimeT {
private java.util.Date date;
public java.util.Date getDate() {
return date;
}
public void setDate(java.util.Date date) {
this.date = date;
}
#Override
public String toString() {
return "DateOrDatetimeT [date=" + date + "]";
}
}
class DateOrPeriodT ->
package org.eclipse.persistence.testing.jaxb.aso.np;
import java.io.Serializable;
import java.util.Date;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElementRef;
import javax.xml.bind.annotation.XmlType;
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "date_or_period_t", propOrder = {
"date", "beginDate", "endDate"
})
public class DateOrPeriodT
implements Serializable {
private final static long serialVersionUID = 1L;
#XmlElementRef(name = "date", type = JAXBElement.class, required = false)
protected JAXBElement<DateOrDatetimeT> date;
#XmlElementRef(name = "begin_date", type = JAXBElement.class, required = false)
protected JAXBElement<Date> beginDate;
#XmlElementRef(name = "end_date", type = JAXBElement.class, required = false)
protected JAXBElement<Date> endDate;
public JAXBElement<DateOrDatetimeT> getDate() {
return date;
}
public void setDate(JAXBElement<DateOrDatetimeT> value) {
this.date = value;
}
public JAXBElement<Date> getBeginDate() {
return beginDate;
}
public void setBeginDate(JAXBElement<Date> value) {
this.beginDate = value;
}
public JAXBElement<Date> getEndDate() {
return endDate;
}
public void setEndDate(JAXBElement<Date> value) {
this.endDate = value;
}
#Override
public String toString() {
return "DateOrPeriodT [date=" + getJAXBElementString(date) + ", beginDate=" + getJAXBElementString(beginDate) + ", endDate=" + getJAXBElementString(endDate) + "]";
}
private String getJAXBElementString(JAXBElement<?> element) {
if (null == element) {
return null;
}
return "{" + element.getName() + ":" + element.getValue() + "}";
}
}
class ObjectFactory
package org.eclipse.persistence.testing.jaxb.aso.np;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlElementDecl;
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
import java.util.Date;
#XmlRegistry
public class ObjectFactory {
#XmlElementDecl(name = "date")
JAXBElement<DateOrDatetimeT> createDate(Date date) {
DateOrDatetimeT dateOrDateTime = new DateOrDatetimeT();
dateOrDateTime.setDate(date);
return new JAXBElement<DateOrDatetimeT>(new QName("date"), DateOrDatetimeT.class, dateOrDateTime);
}
#XmlElementDecl(name = "begin_date")
JAXBElement<Date> createBeginDate(Date date) {
return new JAXBElement<Date>(new QName("begin_date"), Date.class, date);
}
#XmlElementDecl(name = "end_date")
JAXBElement<Date> createEndDate(Date date) {
return new JAXBElement<Date>(new QName("end_date"), Date.class, date);
}
}
file jaxb.properties
javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory
class Test
package org.eclipse.persistence.testing.jaxb.aso.np;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.Unmarshaller;
import java.io.InputStream;
import java.util.HashMap;
public class Test {
public static void main(String[] args) throws Exception {
try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("org/eclipse/persistence/testing/jaxb/aso/date.xml")) {
JAXBContext jc = JAXBContext.newInstance(new Class[]{DateOrPeriodT.class, DateOrDatetimeT.class, ObjectFactory.class}, new HashMap<String, Object>());
Unmarshaller marshaller = jc.createUnmarshaller();
JAXBElement el = (JAXBElement) marshaller.unmarshal(is);
DateOrPeriodT dateOrPeriodT = (DateOrPeriodT) el.getValue();
System.out.println("dateOrPeriodT=" + dateOrPeriodT);
}
}
}
different versions of date.xml (tested with EclipseLink 2.5.2)
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<date>2015-02-16T14:49:46.583+01:00</date>
<begin_date>2015-02-16T14:49:46.583+01:00</begin_date>
<end_date>2015-02-15T14:49:46.583+01:00</end_date>
</date_or_period_t>
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<date>2015-02-16T14:49:46.583+01:00</date>
<begin_date xsi:nil="true" />
<end_date>2015-02-15T14:49:46.583+01:00</end_date>
</date_or_period_t>
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<date>2015-02-16T14:49:46.583+01:00</date>
<begin_date xsi:nil="true" />
<end_date xsi:nil="true" />
</date_or_period_t>
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<begin_date xsi:nil="true" />
<end_date>2015-02-15T14:49:46.583+01:00</end_date>
</date_or_period_t>
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<begin_date xsi:nil="true" />
<end_date xsi:nil="true" />
</date_or_period_t>
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<begin_date>2015-02-15T14:49:46.583+01:00</begin_date>
<end_date>2015-02-15T14:49:46.583+01:00</end_date>
</date_or_period_t>
If you use EclipseLink 2.6.0, xml needs nested date element:
<date_or_period_t xsi:type="date_or_period_t" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<date><date>2015-02-16T14:49:46.583+01:00</date></date>
<begin_date>2015-02-16T14:49:46.583+01:00</begin_date>
<end_date>2015-02-15T14:49:46.583+01:00</end_date>
</date_or_period_t>

Adding default namespace declarations using a generic list wrapper with JAXB

I am all new to JAXB and having wrecked my brains for a week over this I would like to ask the following question. How can I obtain default namespace declarations like these using a generic list wrapper as Blaise Doughan indroduced:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<departments xmlns="urn:example.org/departments">
<department>
<iddepartment>1</iddepartment>
<department>Deparment A</department>
<v_iddepartment>1</v_iddepartment>
</department>
<department>
<iddepartment>2</iddepartment>
<department>Department B</department>
<v_iddepartment>1</v_iddepartment>
</department>
</departments>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<employees xmlns="urn:example.org/employees">
<employee>
<firstname>Tom</firstname>
<lastname>Jones</lastname>
<praefix>Dr.</praefix>
<birthdate>1970-01-01</birthdate>
<ipnumber>1234</ipnumber>
</employee>
<employee>
<firstname>Elvis</firstname>
<lastname>Knoxville</lastname>
<praefix/>
<birthdate>1970-01-02</birthdate>
<ipnumber>4567</ipnumber>
</employee>
</employees>
I have several annotated classes like these:
package org.bp24.server.table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "department", namespace = "urn:example.org/departments")
#XmlType(propOrder = {"iddepartment", "department", "v_iddepartment"})
public class Department {
private int iddepartment;
private String department;
private int v_iddepartment;
public int getIddepartment() {
return iddepartment;
}
public void setIddepartment(int iddepartment) {
this.iddepartment = iddepartment;
}
public String getDepartment() {
return department;
}
public void setDepartment(String department) {
this.department = department;
}
public int getV_iddepartment() {
return v_iddepartment;
}
public void setV_iddepartment(int v_iddepartment) {
this.v_iddepartment = v_iddepartment;
}
}
package org.bp24.server.table;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
#XmlRootElement(name = "employee", namespace = "urn:example.org/employees")
#XmlType(propOrder = {"firstname", "lastname", "praefix", "suffix", "birthdate", "ipnumber"})
public class Employee {
private int idemployee;
private String firstname;
private String lastname;
private String praefix;
private String suffix;
private String birthdate;
private String ipnumber;
private int v_iduser;
#XmlTransient
public int getIdemployee() {
return idemployee;
}
public void setIdemployee(int idemployee) {
this.idemployee = idemployee;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastname() {
return lastname;
}
public void setLastname(String lastname) {
this.lastname = lastname;
}
public String getPraefix() {
return praefix;
}
public void setPraefix(String praefix) {
this.praefix = praefix;
}
public String getSuffix() {
return suffix;
}
public void setSuffix(String suffix) {
this.suffix = suffix;
}
public String getBirthdate() {
return birthdate;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public String getIpnumber() {
return ipnumber;
}
public void setIpnumber(String ipnumber) {
this.ipnumber = ipnumber;
}
#XmlTransient
public int getV_iduser() {
return v_iduser;
}
public void setV_iduser(int v_iduser) {
this.v_iduser = v_iduser;
}
}
Here is the list wrapper I use:
package org.bp24.server.xml.copy;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
public class GenericList <T> {
private List<T> list = new ArrayList<T>();
public GenericList() {
}
public GenericList(List<T> list) {
this.list = list;
}
public void add (T element){
list.add(element);
}
public boolean isEmpty(){
if(list.isEmpty()) return true;
return false;
}
public T get (int pos){
return list.get(pos);
}
#XmlAnyElement(lax=true)
public List<T> getList(){
return list;
}
}
And here is the marshalling code:
package org.bp24.server.xml.copy;
import java.util.HashMap;
import java.util.List;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.namespace.QName;
import org.bp24.server.xml.GenericList;
public class MarshallMatters<T> {
private static volatile HashMap<Class, JAXBContext> contextStore = new HashMap<Class, JAXBContext>();
//synchronized to ensure orderly concurrent contextStore access
private synchronized JAXBContext getContext (Class clazz) throws JAXBException{
if(contextStore.containsKey(clazz)) return contextStore.get(clazz);
JAXBContext context = JAXBContext.newInstance(GenericList.class, clazz);
contextStore.put(clazz, context);
return context;
}
private Class getClassFromList(List<T> list){
if(!list.isEmpty()) return list.get(0).getClass();
return null;
}
public void writeXml(List<T> list) throws JAXBException{
Class clazz = getClassFromList(list);
if(clazz==null){
System.out.println("Error message");
return;
}
JAXBContext jc = getContext(clazz);
GenericList<T> genList = new GenericList<T>(list);
Marshaller m = jc.createMarshaller();
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
QName qn = new QName(clazz.getSimpleName().toLowerCase() + "s");
JAXBElement<GenericList> jaxbe = new JAXBElement<GenericList>(qn, GenericList.class, genList);
m.marshal(jaxbe, System.out);
}
public void readXml(List<T> list) throws JAXBException{
...
}
}
Thank you very much in advance for your help.

jaxb XmlAdapter unmarshall an object from the same xml

take a look at this code :
#XmlRootElement
class Course {
private int id;
private String name;
public Course() {}
public Course(int id, String name) {
super();
this.id = id;
this.name = name;
}
#XmlAttribute(name = "id")
public int getId() {
return id;
}
#XmlAttribute(name = "name")
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
class CourseAdapter extends XmlAdapter<Integer, Course>{
#Override
public Course unmarshal(Integer v) throws Exception {
// what to do hereeeeeeeeeeeeeeee????!!!!
// I want the Course with the id = v unmarshalled from
// the same xml I am unmarshalling at the moment
}
#Override
public Integer marshal(Course v) throws Exception {
return v.getId();
}
}
#XmlRootElement
class Offering {
private int id;
private Course course;
private int capacity;
public Offering() {}
public Offering(int id, Course course, int capacity) {
super();
this.id = id;
this.course = course;
this.capacity = capacity;
}
#XmlAttribute(name = "id")
public int getId() {
return id;
}
#XmlJavaTypeAdapter(CourseAdapter.class)
#XmlAttribute(name = "course")
public Course getCourse() {
return course;
}
#XmlAttribute(name = "capacity")
public int getCapacity() {
return capacity;
}
public void setId(int id) {
this.id = id;
}
public void setCourse(Course course) {
this.course = course;
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
}
#XmlRootElement
class Department {
private String name;
private ArrayList<Course> courses;
private ArrayList<Offering> offerings;
public Department(){}
public Department(String name, ArrayList<Course> courses, ArrayList<Offering> offerings) {
super();
this.name = name;
this.courses = courses;
this.offerings = offerings;
}
#XmlAttribute(name = "name")
public String getName() {
return name;
}
#XmlElement
public ArrayList<Course> getCourses() {
return courses;
}
#XmlElement
public ArrayList<Offering> getOfferings() {
return offerings;
}
public void setName(String name) {
this.name = name;
}
public void setCourses(ArrayList<Course> courses) {
this.courses = courses;
}
public void setOfferings(ArrayList<Offering> offerings) {
this.offerings = offerings;
}
}
I have marshalled my Department and this is the result:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<department name="ece">
<courses id="1" name="farsi"/>
<courses id="2" name="dini"/>
<courses id="2" name="riazi"/>
<offerings capacity="10" course="1" id="1"/>
<offerings capacity="20" course="2" id="2"/>
</department>
the problem is I do not know how to unmarshal course with the id = v from this very xml which is being unmarshalled via "unmarshal" function of CourseAdapter .
You can use #XmlID/#XmlIDREF for this use case without requiring an XmlAdapter.
http://blog.bdoughan.com/2010/10/jaxb-and-shared-references-xmlid-and.html

Resources