unmarshalling empty element with a single attribute
<开发者_StackOverflow中文版animals>
<dog name="Pluto"></dog>
</animals>
If a would like to unmarshall such xml, I need to create classes Animals and Dog.
Is the possibility to create only one class?public class Animals{
private String dog; // value of this field should be "Pluto"
private void setDog(String dog);
private String getDog();
}
How should I annotate methods in Animals?
No, you will still need 2 classes, but you can hide the Dog class, and expose the same methods on your outer class:
public class Animals{
private @XmlElement Dog dog;
public void setDog(String dogName) {
dog = new Dog();
dog.name = dogName;
}
public String getDog() {
return dog.name;
}
public static class Dog {
private @XmlAttribute String name;
}
}
Note: I'm the EclipseLink JAXB (MOXy) lead, and a member of the JAXB (JSR-222) expert group.
Is the possibility to create only one class?
Yes, this can be done in a couple of different ways:
- Using an
XmlAdapter
- Using MOXy's
@XmlPath
extension
Option 1 - XmlAdapter
This approach is similar to what was suggested by skaffman only it keeps the logic out of your domain model:
package forum6871469;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class DogAdapter extends XmlAdapter<DogAdapter.Dog, String> {
@Override
public Dog marshal(String name) throws Exception {
Dog dog = new Dog();
dog.name = name;
return dog;
}
@Override
public String unmarshal(Dog dog) throws Exception {
return dog.name;
}
public static class Dog {
@XmlAttribute
public String name;
}
}
The XmlAdapter
is referenced using the @XmlJavaTypeAdaper
annotation:
package forum6871469;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement
public class Animals{
private String dog; // value of this field should be "Pluto"
@XmlJavaTypeAdapter(DogAdapter.class)
public String getDog() {
return dog;
}
public void setDog(String dogName) {
dog = dogName;
}
}
For More Information
- http://bdoughan.blogspot.com/2010/07/xmladapter-jaxbs-secret-weapon.html
Option 2 - MOXy's @XmlPath Extension
You can use the @XmlPath
extension in MOXy to map this use case:
package forum6871469;
import javax.xml.bind.annotation.XmlRootElement;
import org.eclipse.persistence.oxm.annotations.XmlPath;
@XmlRootElement
public class Animals{
private String dog; // value of this field should be "Pluto"
@XmlPath("dog/@name")
public String getDog() {
return dog;
}
public void setDog(String dogName) {
dog = dogName;
}
}
For More Information
- http://blog.bdoughan.com/2010/07/xpath-based-mapping.html
- http://blog.bdoughan.com/2010/09/xpath-based-mapping-geocode-example.html
- http://blog.bdoughan.com/2011/03/map-to-element-based-on-attribute-value.html
- http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html
精彩评论