Need to rename XML Element with one of its own properties - java

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 */
}

Related

Jackson naming convention issue in serialization with uncommon getter method name

New to java and spring boot.
While trying to serialize the following class,
public class ActionItems {
private String APpID;
public String getAPpID() {
return APpID;
}
public void setAPpID(String aPpID) {
APpID = aPpID;
}
// other fields
}
got the json string as
{
"appID": null,
}
Whilst, cross checking the getter name with decapitilize(), it is matching with the field name.
Introspector.decapitalize("APpID") - gives "APpID"
Is jackson using a different set of rules and methods when generating the property name from the getter method?
PS: I am aware that, variable name should begin with small case. While going through the java beans naming convention spec got this question.
I am using jackson 2.9.3v.
PS: As per the link PropertyNamingStrategy, it should have produced APpID instead of appId right?
Could someone provide some input here?
Thanks.
In Jackson, you can custom PropertyNamingStrategy, and
In absence of a registered custom strategy, default Java property
naming strategy is used, which leaves field names as is, and removes
set/get/is prefix from methods (as well as lower-cases initial
sequence of capitalized characters).
Also, you can custom a property name like:
#JsonProperty("APpID") // produce {"APpID":"s"}
public String getAPpID() {
return APpID;
}

Use JAXB Annotation With Value

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;

Can we change instance variable name with special character in jaxb

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;

Marshal an object as one of its properties with Jackson (as for value objects i.e primitive types wrappers)

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

Changing class without changing a schema

I have a xsd schema which I'm not allowed to change. It produce generated java classes.
Assume that classes looks as follows:
class Data {
protected List<Value> value;
...
}
class Value {
...
}
Now I need to have my own MyValue ideally to be extended from Value.
class MyValue extends Value {
Integer myOwnField1;
Long anotherProperty;
}
And be able to say unmarshaller to use MyValue instead of Value when it parses xml file.
Later I would be able to use the fact that MyValue can contain some useful new fields inside, make operations over them, change them, etc. So I want extend the functionality which I have in schema without changing it.
Is that somehow possible to replace Value by MyValue for unmarshaller?
Apart from the obvious way to create a Map where I can map object which was generated by unmarshaller with my own fields and properties in MyValue. I'd like to avoid this way.
Can you load the list using bean properties?
public void setValue(List<Value> value) {
this.value = ...convert to List<MyValue>...
}
You might be interested in unmarshalling by declared type: indeed, if you override your XSD from the root element to every child element you need to override, you could use a second argument in unmarshal method to sepecify your custom mapping.
<T> JAXBElement<T> unmarshal(Source source,
Class<T> declaredType)
throws JAXBException
[...] declaredType - appropriate JAXB mapped class to hold
source's xml root element
(see Unmarshaller javadoc for more detailed info)

Categories