Jaxb and namespace of inner element - java

I met a problem that looks simple but not obvious to solve.
I have 2 packages with classes marshalled to xml with different namespaces. One class is container for others.
package namespace1;
#XmlRootElement(name = "container", namespace = "urn:nmsp:container:001.02")
#XmlAccessorType(XmlAccessType.FIELD)
#Getter
#Setter
public class Container {
#XmlElement(name = "name")
private String name;
#XmlElement(name = "messages")
private List<Message> messages;
}
-------------------------------------------
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "Message", propOrder = {
"document"
})
public class Message {
#XmlElement(name = "Document", namespace = "urn:iso:std:iso:20022:001", required = true)
protected Document document;
}
-------------------------------------------
package-info.java
#javax.xml.bind.annotation.XmlSchema(namespace = "urn:nmsp:container:001.02",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
xmlns = {
#XmlNs(namespaceURI = "urn:nmsp:container:001.02", prefix = "")
})
package namespace1;
and
package namespace2;
#XmlRootElement(name = "document", namespace = "urn:iso:std:iso:20022:001")
#XmlAccessorType(XmlAccessType.FIELD)
public class Document {
#XmlElement(name = "id")
private String id;
}
package-info.java
#javax.xml.bind.annotation.XmlSchema(namespace = "urn:iso:std:iso:20022:001",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
xmlns = {
#XmlNs(namespaceURI = "urn:iso:std:iso:20022:001", prefix = "")
})
package namespace2;
What I would like to get is:
<container xmlns="urn:nmsp:container:001.02">
<name>Hello</name>
<messages>
<Document xmlns="urn:iso:std:iso:20022:001">
<id>ID1</id>
</Document>
</messages>
</container>
But what I get is:
<container xmlns="urn:nmsp:container:001.02" xmlns:ns2="urn:iso:std:iso:20022:001">
<name>Hello</name>
<messages>
<ns2:Document>
<ns2:id>ID1</ns2:id>
</ns2:Document>
</messages>
</container>
Marshalling code is:
Container conxml = new Container("Hello");
conxml.setMessages(List.of(new Message(new Document("ID1")))));
JAXBContext jc = JAXBContext.newInstance(Container.class);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
StringWriter writer = new StringWriter();
QName _Conxml_QNAME = new QName("urn:nmsp:container:001.02", "container");
JAXBElement<Container> conxmlJAXBElement = new JAXBElement<>(_Conxml_QNAME, Container.class, null, conxml);
marshaller.marshal(conxmlJAXBElement, writer);
System.out.println(writer.toString());
Almost all solutions suggest to fix it with package-info.java but it doesn't help practically.
Can you please give me a hint where I am doing it wrong?
The link to maven project: JaxbTest.7z

The two XML files you give are equivalent, your choice of namespace declaration is a question of taste. The prefixes you set in the #XmlNs annotations are taken into account, when choosing the prefix for each namespace. However, JAXB RI at least, does not redefine them mid-document.
If you want to more directly intervene in the way the XML is generated, you need to add additional components between JAXB and the Writer. E.g. you can use StAX and marshall your document to an XMLStreamWriter like this one (the IndentingXMLStreamWriter comes from TXW2, a dependency of JAXB RI):
private static class RedefineNsXmlStreamWriter extends IndentingXMLStreamWriter {
#Override
public void writeStartElement(String prefix, String localName, String namespaceURI) throws XMLStreamException {
final String known_prefix = getNamespaceContext().getPrefix(namespaceURI);
super.writeStartElement(XMLConstants.DEFAULT_NS_PREFIX, localName, namespaceURI);
if (!XMLConstants.DEFAULT_NS_PREFIX.equals(known_prefix)) {
super.writeNamespace(XMLConstants.DEFAULT_NS_PREFIX, namespaceURI);
}
}
#Override
public void writeNamespace(String prefix, String namespaceURI) throws XMLStreamException {
// Ignore it
}
public RedefineNsXmlStreamWriter(XMLStreamWriter out) {
super(out);
}
}
Then you create an XMLStreamWriter capable of writing to the Writer and serialize:
final XMLStreamWriter xmlWriter = new RedefineNsXmlStreamWriter(XMLOutputFactory.newFactory()//
.createXMLStreamWriter(writerCont));
marshallerCont.marshal(conxmlJAXBElement, xmlWriter);
Of course the RedefineNsXmlStreamWriter get more complicated once you take into account all cases, but it works for your example.

Related

XML parser (Unmarshall) using JaxB to get elemet from xml file

I new to jaxB XML parser. i need to get the all the attribute (idref, type, name, scope) from element tag ** I tried something but getting error.
XML File
<?xml version="1.0" encoding="windows-1252"?>
<xmi:XMIxmi:version="2.1"xmlns:uml="http://www.omg.org/spec/UML/20090901"xmlns:xmi="http://schema.omg.org/spec/XMI/2.1" xmlns:thecustomprofile="http://www.sparxsystems.com/profiles/thecustomprofile/1.0" xmlns:SysML="http://www.omg.org/spec/SysML/20161101/SysML">
<xmi:Documentation exporter="Enterprise Architect" exporterVersion="6.5" exporterID="1555"/>
<xmi:Extension extender="Enterprise Architect" extenderID="6.5">
<elements>
<element xmi:idref="EAPK_5560E5AF_736A_4703_AC79_CA3FAA60984B" xmi:type="uml:Package" name="PackageView" scope="public"></element>
<element xmi:idref="EAPK_59058493_9220_4b05_888A_67C6854C97EC" xmi:type="uml:Package" name="Read from Communication Interface" scope="public">
</element>
<element xmi:idref="EAID_870B8E54_0FF2_4a90_A9C1_23F477DF695F" xmi:type="uml:Activity" name="Read from communication interface" scope="public">
</element>
</elements>
</xmi:Extension>
</xmi:XMI>
Main Class
public class XmlElement {
public static void main(String[] args) {
JAXBContext jaxbContext;
String fileLocation = "C:\\vinoth\\XML_JaxbParser\\elements.xml";
try (FileInputStream fileInputStream = new FileInputStream(fileLocation)) {
System.out.println("******** PARSING START ********");
jaxbContext = JAXBContext.newInstance(Xmi.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
elements elements = (elements) unmarshaller.unmarshal(fileInputStream);
System.out.println(elements);
System.out.println("******** PARSING DONE ********");
} catch (Exception e) {
System.out.println("******** ERROR: SOMETHING WENT WRONG ********");
e.printStackTrace();
}
}
}
elements.java
#XmlRootElement(name = "xmi")
#XmlAccessorType(XmlAccessType.FIELD)
public class Elements {
#XmlElement(name = "elements")
private List<Elements> elements;
// Generate Getters and Setters...
#Override
public String toString() {
return "Elements [elements="+ elements +"]";
}
}
element.java
#XmlAccessorType(XmlAccessType.FIELD)
public class Element {
#XmlAttribute(name = "idref")
private String idref;
#XmlAttribute(name = "type")
private String type;
#XmlAttribute(name = "name")
private String name;
#XmlAttribute(name = "scope")
private String scope;
//Generate Getters and Setters...
#Override
public String toString() {
return "Element [idref=" + idref + ",type=" + type + ", name=" + name + ", scope=" + scope+ "]";
}
}
I need to get the the element attribute from the given XML file. I don't know where I made a mistake. Root element and parent and children, i can understand mistake from mapping section. but I couldn't sort out.
Your XML file uses many different XML namespaces,
which you need to consider in your Java code.
Especially notice, that the namespace URIs (e.g.
"http://schema.omg.org/spec/XMI/2.1") are the
only relevant thing. The namespace prefixes (e.g. xmi:) are not
relevant for Java. They were only invented to make the XML
easier to read for humans.
I recommend to define all your XML namespace URIs as Java
string contants to avoid typing them many times in your code:
public class NameSpaces {
public final static String UML = "http://www.omg.org/spec/UML/20090901";
public final static String XMI = "http://schema.omg.org/spec/XMI/2.1";
public final static String THE_CUSTOM_PROFILE = "http://www.sparxsystems.com/profiles/thecustomprofile/1.0";
public final static String SYSML = "http://www.omg.org/spec/SysML/20161101/SysML";
}
You need to carefully look at your XML content (XML elements
XMI, Documentation, Extension, Elements, Element and
their XML attributes) to see which XML namespace is used where.
Then in all your Java classes you need to specify the right
namespace in the #XmlAttribute and #XmlElement annotations.
You will also need to specify a namespace in the #XmlRootElement
annotation of your root class.
See also the Javadoc of the JAXB annotations.
I will not do all your work for you, but instead only show how
your root class and the Element class may look like.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlRootElement(name = "XMI", namespace = NameSpaces.XMI)
public class XMI {
#XmlAttribute(name = "version", namespace = NameSpaces.XMI)
private String version;
#XmlElement(name = "Documentation", namespace = NameSpaces.XMI)
private Documentation documentation;
#XmlElement(name = "Extension", namespace = NameSpaces.XMI)
private Extension extension;
// Getters, setters, toString omitted here for brevity
}
#XmlAccessorType(XmlAccessType.FIELD)
public class Element {
#XmlAttribute(name = "idref", namespace = NameSpaces.XMI)
private String idref;
#XmlAttribute(name = "type", namespace = NameSpaces.XMI)
private String type;
#XmlAttribute(name = "name")
private String name;
#XmlAttribute(name = "scope")
private String scope;
// Getters, setters, toString omitted here for brevity
}

Why return null my method with JAXB unmarshalling convert sting xml to object?

I am trying to convert my xml string to objects. I have the following code, but when I do get to a field it returns null.
#Override
public DatosInputDto convertXmlToDatosInputDto (String xml) {
DatosInputDto input = null;
try {
JAXBContext jaxbContext = JAXBContext.newInstance(DatosInputDto.class);
Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
StringReader reader = new StringReader(xml);
input = (DatosInputDto) unmarshaller.unmarshal(reader);
} catch (JAXBException ex) {
LOGGER.error(ex.getMessage(), ex);
}
return input;
}
This is the xml of string:
<?xml version="1.0" encoding="UTF-8"?>
<nd0:OU_SchemaPublic xmlns:nd0="http://www.prueba/cadena/ejemplo/1.00">
<nd0:TTT_Code>LIM28</nd0:TTT_Code>
<nd0:TTT_Date>20210622</nd0:TTT_Date>
<nd0:TTT_CodeType>0203</nd0:TTT_CodeType>
<nd0:TTT_Receiver>0098</nd0:TTT_Receiver>
<nd0:TTT_SenderPT>0092</nd0:TTT_SenderPT>
<nd0:TTT_DocumentFile>Documents</nd0:TTT_DocumentFile>
</nd0:OU_SchemaPublic>
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {"code", "date", "codeType", "receiver", "senderPt","documentFile"})
#XmlRootElement(name = "OU_SchemaPublic")
public class DatosInputDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = -4596758570871609534L;
private String code;
private String date;
private String codeType;
private String receiver
private String senderPt;
private String documentFile;
}
package.info
#javax.xml.bind.annotation.XmlSchema(
xmlns = {#javax.xml.bind.annotation.XmlNs(prefix = "nd0",
namespaceURI = "http://www.prueba/cadena/ejemplo/1.00")},
namespace = "http://www.prueba/cadena/ejemplo/1.00",
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
package com.prueba;
What is my mistake?
What do I need to add or remove?
Your XML attributes name different from Pojo class. Add below annotations on fields.
#XmlAttribute
private String code
If not work then add the key name as below.
#XmlAttribute(name="nd0:TTT_Code")
private String code

How to generate one objects from two similar xml documents with jaxb

I'm trying to integrate with some provider REST API within xml. I have two requests and two very similar responses: Operation response and Check response.
Operation:
<Response>
<ReturnCode>0</ReturnCode>
<ReturnMessage>OK</ReturnMessage>
<Commands>
<OperationResponseCommand>
<ResultCode>412</ResultCode>
<ResultMessage>Some message hear</ResultMessage>
<OperationId>125206188472552900</OperationId>
<Id>14507921</Id>
</OperationResponseCommand>
</Commands>
</Response>
Check:
<Response>
<ReturnCode>0</ReturnCode>
<ReturnMessage>OK</ReturnMessage>
<Commands>
<CheckResponseCommand>
<ResultCode>412</ResultCode>
<ResultMessage>Some message hear</ResultMessage>
<OperationId>125206188472552900</OperationId>
</CheckResponseCommand>
</Commands>
</Response>
As you can see, the differences are:
<OperationResponseCommand> instead of <CheckResponseCommand>
in first xml.
One additional tag <Id> inside
<OperationResponseCommand>.
And I have two classes for Response and for Command.
First:
#Data
#XmlRootElement(name = "Response")
#XmlAccessorType(XmlAccessType.FIELD)
public class Response {
#XmlElement(name = "ReturnCode")
private Integer returnCode;
#XmlElement(name = "ReturnMessage")
private String returnMessage;
#XmlElementWrapper(name = "Commands")
#XmlElement(name = "OperationResponseCommand")
private List<Command> commands = new ArrayList<>();
}
Second:
#Data
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Command {
#XmlElement(name = "ResultCode")
private Integer resultCode;
#XmlElement(name = "ResultMessage")
private String resultMessage;
#XmlElement(name = "OperationId")
private String operationId;
#XmlElement(name = "Id")
private Integer id;
}
For building response object from xml I'm using this class:
public class JAXBOperations {
public <T> T buildObjectFromXml(Class<T> clazz, String xml) {
try {
StringReader reader = new StringReader(xml);
Unmarshaller unmarshaller = createUnmarshaller(clazz);
return (T) unmarshaller.unmarshal(reader);
} catch (JAXBException e) {
throw new RuntimeException("Exception has been occurred while creating unmarshaller to parse xml to object");
}
}
public <T> String buildXmlFromObject(T objectToXml) {
try {
StringWriter writer = new StringWriter();
Marshaller marshaller = createMarshaller(objectToXml.getClass());
marshaller.marshal(objectToXml, writer);
return writer.toString();
} catch (JAXBException e) {
throw new RuntimeException("Exception has been occurred while creating marshaller to parse object to xml");
}
}
private <T> Marshaller createMarshaller(Class<T> clazz) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
return jaxbContext.createMarshaller();
}
private <T> Unmarshaller createUnmarshaller(Class<T> clazz) throws JAXBException {
JAXBContext jaxbContext = JAXBContext.newInstance(clazz);
return jaxbContext.createUnmarshaller();
}
}
Method buildObjectFromXml. And it works fine for first xml response. I have an object like this:
Response(
returnCode=0, returnMessage=OK,
commands=[Command(
resultCode=417,
resultMessage=Processing,
operationId=b6619f26-8583-4272-b89d-d1b200109d06,
id=157427079)])
But for the second xml response it doesn't works. I have:
Response(
returnCode=0,
returnMessage=OK,
commands=[])
I tried to change the code of my Response class. Like this:
#Data
#XmlRootElement(name = "Response")
#XmlAccessorType(XmlAccessType.FIELD)
public class tResponse {
#XmlElement(name = "ReturnCode")
private Integer returnCode;
#XmlElement(name = "ReturnMessage")
private String returnMessage;
#XmlElementWrapper(name = "Commands")
#XmlElementRefs({
#XmlElementRef(name = "OperationResponseCommand", type = Command.class),
#XmlElementRef(name = "CheckResponseCommand", type = Command.class)})
private List<Command> commands = new ArrayList<>();
}
Or this:
#Data
#XmlRootElement(name = "Response")
#XmlAccessorType(XmlAccessType.FIELD)
public class Response {
#XmlElement(name = "ReturnCode")
private Integer returnCode;
#XmlElement(name = "ReturnMessage")
private String returnMessage;
#XmlElementWrapper(name = "Commands")
#XmlElement(name = "OperationResponseCommand")
private List<Command> operstionCommands = new ArrayList<>();
#XmlElementWrapper(name = "Commands")
#XmlElement(name = "CheckResponseCommand")
private List<Command> checkCommands = new ArrayList<>()
}
But it both doesn't works too.
My question is: what I'm doing wrong? How can I change code of my two classes to correct converting to object both types of xml responses?
For representing the XML elements <OperationResponseCommand>
and <CheckResponseCommand> you will need separate classes
which should be subclasses of your Command classes.
Let's call them OperationResponseCommand and CheckResponseCommand.
The properties common to all commands should remain in your
Command class. It is also a good idea to declare this class as abstract.
#Data
#XmlAccessorType(XmlAccessType.FIELD)
public abstract class Command {
#XmlElement(name = "ResultCode")
private Integer resultCode;
#XmlElement(name = "ResultMessage")
private String resultMessage;
#XmlElement(name = "OperationId")
private Integer operationId;
}
The properties specific for the commands should go into the subclasses:
#Data
#XmlAccessorType(XmlAccessType.FIELD)
public class OperationResponseCommand extends Command {
#XmlElement(name = "Id")
private Integer id;
}
#Data
#XmlAccessorType(XmlAccessType.FIELD)
public class CheckResponseCommand extends Command {
}
Finally, in your Response class you need to enhance the annotations
of your List<Command> commands property, so that JAXB
will know which object class needs to be instantiated depending
on the XML element name of the commands.
(See also the javadoc of #XmlElements.)
#XmlElementWrapper(name = "Commands")
#XmlElements({
#XmlElement(name = "OperationResponseCommand", type = OperationResponseCommand.class),
#XmlElement(name = "CheckResponseCommand", type = CheckResponseCommand.class)
})
private List<Command> commands = new ArrayList<>();

javax.xml.bind.UnmarshalException: unexpected element (uri:""

I am getting an exception while turning an XML response from a service to a POJO. The XML looks like this:
Here is my XML response.
javax.xml.bind.UnmarshalException: unexpected element (uri:""
, local:"ItemSearchResponse"). Expected elements are
<{http://webservices.amazon.com/AWSECommerceService/2011-08-01}ItemSearchResponse>
I am using it like this:
Document response = getResponse(url);
JAXBContext context = JAXBContext.newInstance(AmazonItem.class);
Unmarshaller unMarshaller = context.createUnmarshaller();
newItem = (AmazonItem) unMarshaller.unmarshal(response);
Below are the details of my files
package-info.java
#XmlSchema(
namespace = "http://webservices.amazon.com/AWSECommerceService/2011-08-01",
elementFormDefault = XmlNsForm.QUALIFIED)
package com.services.amazon;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
AmazonItem.java
#XmlRootElement(name="ItemSearchResponse")
#XmlAccessorType(XmlAccessType.FIELD)
public class AmazonItem
{
#XmlElement(name="Items")
private Items items = null;
}
Items.java
#XmlAccessorType(XmlAccessType.FIELD)
public class Items {
#XmlElement(name="Item")
List<Item> items = new ArrayList();
}
Item.java
#XmlAccessorType(XmlAccessType.FIELD)
public class Item {
#XmlElement(name="ASIN")
private String asin;
#XmlElement(name="ItemAttributes")
private ItemAttributes attributes;
#XmlElement(name="ItemLinks")
private List<ItemLinks> itemLinks;
}
ItemAttributes.java
#XmlAccessorType(XmlAccessType.FIELD)
public class ItemAttributes {
#XmlElement(name="Title")
private String title;
#XmlElement(name="Actor")
private List<String> actor;
#XmlElement(name="ProductGroup")
private String productGroup;
}
ItemLink.java
#XmlAccessorType(XmlAccessType.FIELD)
public class ItemLink {
#XmlElement(name="Description")
private String description;
#XmlElement(name="URL")
private String url;
}
ItemLinks.java
#XmlAccessorType(XmlAccessType.FIELD)
public class ItemLinks {
#XmlElement(name="ItemLink")
List<ItemLink> itemLinks;
}
The error message is saying that you are getting an XML document that looks like this:
<ItemSearchResponse>
Instead of one like the following that matches the namespace qualification that you have mapped:
<ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2011-08-01">
The explanation is here:
The JAXBContext instance is intialized with class(es) passed as parameter(s) and classes that are statically reachable from these class(es).
Initialize JAXBContext using package, so it can see #XmlSchema declared in package-info.java:
JAXBContext.newInstance("com.services.amazon")
If you're using DocumentBuilderFactory in your getResponse method, try setting namespace awareness:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
I had the same UnmarshalException and this solved it.
Remove the namespace from package-info.java and change
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED
to
elementFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED.
Remove the namespace from package-info.java
It's work for me
Ex:
#javax.xml.bind.annotation.XmlSchema(namespace = "", elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)

Getting incorrect values while converting an XML into a Java Object

I m trying to convert XML file into Java Object using Jaxb unmarshalling.
public static void main(String[] args) {
String input = "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">"+
" <key>1</key>" +
"<income>100.335</income>" +
"</project>" ;
NexusClient c1 = new NexusClient();
c1.getObject(input);
}
/*********/
public boolean getObject(String input) {
InputSource inputSource = new InputSource(new StringReader(input));
System.out.println(inputSource);
try {
JAXBContext jaxbContext = JAXBContext
.newInstance(mavenEntity.class);
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
mavenEntity mavenObject = (mavenEntity) jaxbUnmarshaller
.unmarshal(inputSource);
System.out.println("Success"+mavenObject.getIncome());
} catch (JAXBException e) {
System.out.println("Unable to parse the XML Context");
e.printStackTrace();
return false;
}
return true;
}
I m facing an issue while trying to extract "Income" tag information. I couldn't extract correct values using Jaxb. My pojo class is :
#XmlRootElement(name = "project", namespace = "http://maven.apache.org/POM/4.0.0")
#XmlAccessorType(XmlAccessType.FIELD)
public class mavenEntity {
#XmlElement(name = "key", type = String.class)
private String key;
#XmlElement(name = "income", type = String.class)
private String income;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getIncome() {
return income;
}
public void setIncome(String income) {
this.income = income;
}
}
I m getting Null as output for any tag in XML. I guess there is some problem with my name space in XML Annotation. But I really don't understand what it is. Before posting this, I did some groundwork by referring to few links similar to this But still my result is incorrect. Can some one help me out.
The namespace qualification in your model does not match the document. Instead of specifying the namespace on #XmlRootElement and all instances of #XmlElement you can specify the namespace qualification at the package level using #XmlSchema.
package-info.java
#XmlSchema(
namespace = "http://maven.apache.org/POM/4.0.0",
elementFormDefault = XmlNsForm.QUALIFIED)
package org.example.foo;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
mavenEntity.java
I have removed the unnecessary annotations from this class (see: http://blog.bdoughan.com/2012/07/jaxb-no-annotations-required.html).
package org.example.foo;
import javax.xml.bind.annotation.XmlSchema;
#XmlRootElement(name = "project")
#XmlAccessorType(XmlAccessType.FIELD)
public class mavenEntity {
private String key;
private String income;
}
For More Information
http://blog.bdoughan.com/2010/08/jaxb-namespaces.html
You will need to add namespace to your #XmlElement annotated fields too
#XmlElement(name = "key", namespace = "http://maven.apache.org/POM/4.0.0")
private String key;
#XmlElement(name = "income", namespace = "http://maven.apache.org/POM/4.0.0")
private String income;
That's because your root element has a particular namespace. Since the nested elements don't have namespace prefix, they are using the root's. I guess this is required by JAXB.
Some alternatives and/or explanations here and here.

Categories