When generating XML using JAXB annotations, I know it's not possible to use #XmlElement(name="City") & #XmlValue on the same Java member because they are mutually exclusive. Is it possible to #XmlElement to produce an XML tag with a value at the same time? Not being able to do this causes a ton of objects to be created and seems to be overkill.
Java Code
....
#XmlElement(name="City")
#XmlValue <---- I'm wanting to do this but I'm limited by the API
private String city;
Expected Output
....
<City>some value here</City>
....
We can try to achieve the same using another type which uses #XmlValue annotation.
Below is what you can try -
#XmlRootElement(name="CityRoot")
#XmlType(name="CityRootType")
public class CityRoot {
#XmlElement(name="City")
public CityName s;
}
CityName definition as below
public class CityName {
#XmlValue
String name;
}
Now, feed these two files to schemagen to have the .xsd file generated and using that generate .xml file to verify.
Below is how generated xml file looks like when I generated it -
<?xml version="1.0" encoding="UTF-8"?>
<CityRoot>
<City>SomeCityName</City>
</CityRoot>
If you want to have an element with simple text, the only annotation you need is the #XmlElement annotation. If the type of a field is String, JAXB generates an xml element with the value of the String as the value of the element.
The only thing you need is this:
#XmlElement(name="City")
private String city;
Related
I'm trying to rewrite some API serialization from custom mappers to annotation-based style and faced with one hard mapping (which was earlier custom-serialized to json and xml separately) that I can not "translate" to. (Serialization is made with Jackson.)
In the POJO we have a collection, e.g.
class Data {
Set<Integer> tags;
}
which should be serialized in xml like:
<tags>
<tag id="1"/>
<tag id="2"/>
</tags>
and in json like:
{
"tags":[1,2]
}
Strait method with
#XmlElementWrapper(name="tags")
#XmlElement(name="tag")
gives good json, but incorrect xml like
<root>
<tags>
<tag>1<tag/>
<tag>2<tag/>
</tags>
</root>
cause there is no attribute specification.
I tried to wrap a bit with:
class Data{
#XmlElementWrapper(name="tags")
#XmlElement(name="tag")
Set<Tag> tags;
}
class Tag{
#XmlAttribute(name="id")
Integer id;
}
But this produces unwanted key in json format, like:
"tags":[
{"tag":{"id":1}},
{"tag":{"id":2}}
]
Ok, then. I tried to specify custom json serializer(implementing JsonSerializer and injecting with #JsonSerialize(using = ...) ), but seems it also affects xml "render".
Is it possible to do the trick with annotations only? Or mb is it possible somehow use default json serialization and custom xml serializtaion for some class? .e.g.
use custom xml serialization only for Reasons class in such way
class Data {
#XmlElement("tags")
Reasons tags;
}
but let all surrounding data be "render" with general strategy.
Simply create a getter annotated with #JsonValue will tell Jackson to produce a single value, without any field name.
This mapping:
#XmlRootElement
public class Data{
public Set<Tag> tags;
}
public class Tag{
#XmlAttribute
public Integer id;
#JsonValue
public Integer getId() {
return id;
}
}
Will then produce:
{"tags":[2,1]}
And:
<data><tags id="2"/><tags id="1"/></data>
PS: You're using JAXB annotations, i don't think Jackson will honor them.
To get the XML result above, you need to use JAXB:
StringWriter writer = new StringWriter();
JAXBContext context = JAXBContext.newInstance(Data.class, Tag.class);
Marshaller m = context.createMarshaller();
m.marshal(value, writer);
System.out.println(writer.getBuffer().toString());
As a final note, i'm not super fan of using a single mapping for multiple representations. It's probably good for simple stuff, but if your code grows more complex than this, i strongly suggest you create two sets of classes (one for XML mapping and one for JSON), maybe with a common interface.
I know we can use #XMLRootElement annotation to set the name by which we want this to appear in XML after object to xml conversion using JAXB but I am looking about the way so that XML Elements can be renamed with one of its own properties like for the POJO
class Field
{
String fieldName;
String fieldValue;
//getter/setter
}
after object to xml conversion using JAXB, instead of
<Field>
<fieldName>FirstName</fieldName>
<fieldValue>Rahul</fieldValue>
</Field
I need the above xml formatted as
<FirstName>Rahul</FirstName>
I know I can simply get this if I declare FirstName as String but somehow I need to do as explained above.
If you are using MOXy/Eclipselink then there is #XmlVariableNode annotation available. You would need to specify it on the object that holds the Field (if Field is the root then I fear #XmlVariableNode won't help). Example:
class Field {
#XmlTransient
String fieldName;
#XmlValue
String fieldValue;
}
class Holder {
#XmlVariableNode("fieldName")
Field field;
}
Note that #XmlVariableNode is a MOXy specific annotation. It appears to be available since 2.6 version.
Yes you can set the name of the properties like you want them to appear by annotating them with #JsonProperty(...).
In your can you can do something as follows:
class Field
{
#JsonProperty("FirstName")
String fieldName;
String fieldValue;
/* Getter-Setters */
}
I am using JAXB and jersey for my project. Here is my model class:
#XmlRootElement(name="volume")
#JsonRootName(value="volume")
public class Volume{
#XmlAttribute(name="os-vol:name")
public String name;
}
Desire Output:
{"volume":{"os-vol:name":"vol-1"}}
Is there any way so that i could change the instance variable "name" to "os-vol:name" in both xml and json. I used #JsonProperty,but it worked for JSON only. Any other way so that it can represent both JSON as well as XML simultaneously.
Use the annotation JsonProperty:
#JsonProperty(name="os-vol:name")
public String name;
EDIT: Previous answer does not work (it stills create a nested object)
I'm using Jersey and Jackson.
I got a class like
#XmlAccessorType(XmlAccessType.NONE)
public class Name {
private String value;
#XmlValue
public String getValue(){...}
public void setValue(String value){...}
}
used as in
public class Person{
#XmlElement(name = "IDName")
public Name getName(){...}
}
I'd like to marshal Name object as the value of it's identity property.
How can I achieve that?
<Person>
<IDName>foo</IDName>
</Person>
instead of
<Person>
<IDName>
<Value>foo</Value>
</IDName>
</Person>
I'd tried both to indicate in Person that Name object should be marshalled as itself.getValue() and either to indicate within Name class to marshal without any element wrapper (its fields directly) with no luck.
A possible solution is replacing #XmlValue annotation with Jackson's #JsonValue to make it work (tested).
I infer from http://wiki.fasterxml.com/JacksonJAXBAnnotations that it can be the only solution for now
According to this the official documentation
#javax.xml.bind.annotation.XmlValue
The field/property to which this annotation is applied will be named "value".
So maybe it's limited by design. Any better answer, specially if using JAXB annotations alone, will be much appreciated
I use Spring and Apache CXF for my project that implements java Web Services with first-code style.
I have a variable as defined:
#XmlTransient
public String word;
So that variable doesn't map to an attribute at XML.
However I want it to be ignored to mapping XML element at serialization but not at deserialization.
How can I do that?
I don't think you can achieve that with #XmlTransient. An option would be to use MOXy to marshal using one schema and unmarshal using another schema. You can find a great example here.
A simple but less elegant workaround would be something like this:
#XmlTransient
public String word;
public void setDeserializedWord(String word) {
this.word = word;
}
#XmlElement(name="word")
public String getDeserializedWord() {
return null;
}