How to map complex XML element to Java class property using JAXB - java

I need to map my XML snippet onto Java class using JAXB, but have a tricky case. I have the following XML:
<person>
<name part="first">Richard</name>
<name part="last">Brooks</name>
</person>
and need to map it onto the following class
public class Person {
private String firstName;
private String lastName;
}
Could you please help me to figure out JAXB annotations to make it possible?

You can do this with MOXy, see #XmlPath.
#XmlPath("name[#part='first']/text()")
private String firstName;
#XmlPath("name[#part='last']/text()")
private String lastName;
Related questions:
Using #XmlPath with jaxb/MOXy to map complex type

Here is one approach you could take, but would require you to create a separate class for Name:
#XmlRootElement
public class Person {
#XmlElement(name="name")
private List<Name> names;
...
}
public class Name {
#XmlAttribute
private String part; //would be set to "first" or "last"
#XmlValue
private String nameValue;
...
}

Related

how to wrap non collection property in xml?

I know this question was asked before, but still no response to that.
Indeed, I have this Java Entity:
#Entity
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String email;
private String firstName;
private String lastName;
}
and my goal is to transform/map the class below into this xml format:
<customer>
<id>...</id>
<email>....</email>
<names>
<firstName>...</firstName>
<lastName>...</lastName>
<names>
</customer>
The problem is that I can't use #XmlElementWrapper because it is not applicable on non collection property, and I'm searching for a solution that doesn't require to create a class "names" which will contains firstname and lastname.

Spring Data Mongodb Using Object Type to Collection

Newbie Alert !
I just installed mongodb 2 days back and started creating REST api's over spring.
So i have a collection, userinfo, where a sample document would look like
{"_id":"5c62588e5e1fbc37dc9746d3","name":{"first":"rajan","last":"rawat"},"age":32}
I created the field name as Object type in the collection.
Now creating the entity class for it in java
#Document(collection = "userinfo")
public class UserInfo {
#Id
private String id;
private Name name;
private int age;
}
where the Class Name is
public class Name {
private String firstName;
private String lastName;
}
On running the API, the response I get is
{"id":"5c62588e5e1fbc37dc9746d3","name":{"firstName":null,"lastName":null},"age":32}
If I change the type in UserInfo class to string like,
#Document(collection = "userinfo")
public class UserInfo {
#Id
private String id;
private String name;
private int age;
}
The response changes to
{"id":"5c62588e5e1fbc37dc9746d3","name":"{ \"first\" : \"rajan\",
\"last\" : \"rawat\" }","age":32}
which basically gives a string representation of the object from collection.
My Questions.
Is there something wrong with the way I designed the collection in mongoDB. I am assuming my use case is a reason why the Object type would have been introduced.
How do I map this collection in java i.e #Document. What am I missing ? Is there Something else I need to configure in the Class Name
In your document your attributes name are "first" and "last", so in your class Name you need to use the same names so that the object can be mapped by spring.
just try this:
public class Name {
private String first;
private String last;
}

Storing XML Tag content to different variable using JAXB

I'm currently having a issue in my Project that involes an XML stored in a String variable. I'm trying to save the content of the XML in different variables.
Using the common JAXB method that involes the same variable name and the tag name should solve my problem. In this case, I have to store in different variable names.
This is my XML
<?xml version="1.0" encoding="UTF-8"?>
<PORTAL>
<NAME>PERSON 2.0</NAME>
<ID>99995</ID>
<DATAGENERATIO>2008-04-10</DATAGENERATIO>
<HOURGENERATIO>05:07:35</HOURGENERATIO>
<LANGUAGE>EN</LANGUAGE>
<XMLVERSIO>1.0</XMLVERSIO>
</PORTAL>
And this is the class used to store the content of that XML.
#XmlRootElement(name="PORTAL")
public class ApiPubPortal {
private long idPortal;
private String idIdioma;
private String nombre;
private Date dataGeneracio;
private String versionXml;
}
I already try using #XmlElement(name="ID") but it gives me IllegalAnnotationExceptions
If anybody can help me with this I'll be thankfully.
You need to make sure that you have getter and setters for all your private fields. An example given below:
private long idPortal;
#XmlElement(name = "ID")
public long getIdPortal()
{
return idPortal;
}
public void setIdPortal(long idPortal)
{
this.idPortal = idPortal;
}
Please note to put #XmlElement(name = "ID") on your getter.
With SimpleXml you can use the #XmlName annotation to tell the parser what the XML tag name is that is linked to a field. There is no need for getters and setters in your POJO. This will work:
#XmlName("PORTAL")
public class ApiPubPortal {
#XmlName("ID")
private long idPortal;
private String idIdioma; // Its not clear to which XML tag this maps
#XmlName("NAME")
private String nombre;
#XmlName("DATAGENERATIO")
private String dataGeneracio;
#XmlName("XMLVERSIO")
private String versionXml;
}
Your XML can then be serialized this way:
final String xml = ...
final SimpleXml simple = new SimpleXml();
final ApiPubPortal portal = simple.fromXml(xml, ApiPubPortal.class);
The library is in maven central:
<dependency>
<groupId>com.github.codemonstur</groupId>
<artifactId>simplexml</artifactId>
<version>1.4.0</version>
</dependency>

JAXB Element Wrapper for a Single Group of Elements When Marshalling

I wish to have an XML structure like this:
<?xml version="1.0" encoding="UTF-8"?>
<MSG>
<CASE>
<Field1></Field1>
<Field2></Field2>
</CASE>
</MSG>
The problem is, with the #XmlElementWrapper, I need a collection of items but there will be only 1 case item. How can I have multiple root elements, for a single collection of elements? Preferably in a single class.
I want something like this, but it throws an exception.
#XmlRootElement( name="MSG")
public class XMLStructure {
#XmlElementWrapper(name="CASE")
#XmlElement(name = "Field1")
private String field1;
#XmlElementWrapper(name="CASE")
#XmlElement(name = "Field2")
private String field2;
}
In the EclipseLink MOXy implementation of JAXB (JSR-222) we have an #XmlPath extension that enables you to map this as:
#XmlRootElement( name="MSG")
#XmlAccessorType(XmlAccessType.FIELD)
public class XMLStructure {
#XmlPath("CASE/Field1/text()")
private String field1;
#XmlPath("CASE/Field2/text()")
private String field2;
}
For More Information
I have written more about the #XmlPath extension on my blog:
http://blog.bdoughan.com/2010/07/xpath-based-mapping.html

jaxb create xml attribute

I want to create xml from my object, but instead of xml nodes I'd like to create attribute i.e.
#XmlRootElement
class MyObject{
private String name;
private String age;
...getters/setters...
}
And I want my object to create this xml :
<MyObject name="something">
<age></age>
</MyObject>
How can I do this?
You can use the #XmlAttribute annotation to map to an XML attribute.
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
class MyObject{
#XmlAttribute // Maps to an XML attribute
private String name;
private String age; // Maps to an XML element
...getters/setters...
}

Categories

Resources