开发者

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:

  1. Using an XmlAdapter
  2. 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
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜