如何在JAXB中更改对象中的XmlRootElement的名称?(How to change the name of the XmlRootElement in JAXB deppending on

编程入门 行业动态 更新时间:2024-10-24 05:20:06
如何在JAXB中更改对象中的XmlRootElement的名称?(How to change the name of the XmlRootElement in JAXB deppending on the object?)

我有以下对象

电影

@Entity @Table(name="film") @XmlRootElement(name = "film") public class Film implements Serializable { @Id @Column(name="id") private String fbId; @Column(name="title") private String title; @ManyToMany @JoinTable( name="direction", joinColumns={@JoinColumn(name="film", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="person", referencedColumnName="id")}) private Collection<Person> directors; @OneToMany(cascade={CascadeType.ALL}, mappedBy="film") @MapKey(name="character") private Map<String, Performance> performances; //GETTERS @XmlAttribute(name = "fbId") public String getFreebaseId() { return this.fbId; } @XmlElementRefs({ @XmlElementRef(name="director", type=Person.class) }) public Collection<Person> getDirectors() { return this.directors; } @XmlAnyElement(lax=true) public Collection<Performance> getPerformances() { ArrayList performancesArray = new ArrayList<Performance>(); for (Map.Entry<String, Performance> entry : this.performances.entrySet()) { Performance value = entry.getValue(); performancesArray.add(value); } return performancesArray; } }

@Entity @Table(name="person") public class Person implements Serializable { @Id @Column(name="id") private String fbId; @Column(name="first_name") private String firstName; @Column(name="last_name") private String lastName; @OneToMany(cascade={CascadeType.ALL}, mappedBy="actor") @XmlTransient private Collection<Performance> performances; //GETTERS @XmlAttribute(name = "fbId") public String getFreebaseId() { return this.fbId; } @XmlElement(name = "firstName") public String getFirstName() { return this.firstName; } @XmlElement(name = "lastName") public String getLastName() { return this.lastName; } @XmlTransient public Collection<Performance> getPerformances() { return this.performances; } }

每部电影都有一个(或许多)导演和表演,即“人物”。 我不需要为导演上课,但我会为性能而做,因为他们有更多的信息。

性能

@Entity @Table(name="performance") @XmlRootElement(name = "performace") public class Performance implements Serializable { @Id @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="film") private Film film; @Id @Column(name="film_character") private String character; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="actor") private Person actor; //TO STRING public String toString() { return this.actor.toString() + " - " + this.character; } //GETTERS @XmlTransient public Film getFilm() { return this.film; } @XmlElementRefs({ @XmlElementRef(name = "firstName", type = Person.class), @XmlElementRef(name = "lastName", type = Person.class) }) public Person getActor() { return this.actor; } @XmlElement(name = "character") public String getCharacter() { return this.character; } }

当我通过JAXB运行时,我得到了这个:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <film fbId="1"> <description>Nice film</description> <person fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </person> <performace> <person fbId="4"> <firstName>Steve</firstName> <lastName>Buscemi</lastName> </person> <character>Billy</character> </performace> <performace> <person fbId="2"> <firstName>Jhon</firstName> <lastName>Travolta</lastName> </person> <character>Vincent</character> </performace> <performace> <person fbId="3"> <firstName>Samuel</firstName> <lastName>L Jackson</lastName> </person> <character>Jules</character> </performace> <performace> <person fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </person> <character>Jimmie</character> </performace> <title>Pulp Fiction</title> </film>

有没有办法改变“人”的名字? 得到这样的东西:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <film fbId="1"> <description>Nice film</description> <director fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </director> <performace fbId="4"> <firstName>Steve</firstName> <lastName>Buscemi</lastName> <character>Billy</character> </performace> <performace fbId="2"> <firstName>Jhon</firstName> <lastName>Travolta</lastName> <character>Vincent</character> </performace> <performace fbId="3"> <firstName>Samuel</firstName> <lastName>L Jackson</lastName> <character>Jules</character> </performace> <performace fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> <character>Jimmie</character> </performace> <title>Pulp Fiction</title> </film>

I have the following objects

Film

@Entity @Table(name="film") @XmlRootElement(name = "film") public class Film implements Serializable { @Id @Column(name="id") private String fbId; @Column(name="title") private String title; @ManyToMany @JoinTable( name="direction", joinColumns={@JoinColumn(name="film", referencedColumnName="id")}, inverseJoinColumns={@JoinColumn(name="person", referencedColumnName="id")}) private Collection<Person> directors; @OneToMany(cascade={CascadeType.ALL}, mappedBy="film") @MapKey(name="character") private Map<String, Performance> performances; //GETTERS @XmlAttribute(name = "fbId") public String getFreebaseId() { return this.fbId; } @XmlElementRefs({ @XmlElementRef(name="director", type=Person.class) }) public Collection<Person> getDirectors() { return this.directors; } @XmlAnyElement(lax=true) public Collection<Performance> getPerformances() { ArrayList performancesArray = new ArrayList<Performance>(); for (Map.Entry<String, Performance> entry : this.performances.entrySet()) { Performance value = entry.getValue(); performancesArray.add(value); } return performancesArray; } }

Person

@Entity @Table(name="person") public class Person implements Serializable { @Id @Column(name="id") private String fbId; @Column(name="first_name") private String firstName; @Column(name="last_name") private String lastName; @OneToMany(cascade={CascadeType.ALL}, mappedBy="actor") @XmlTransient private Collection<Performance> performances; //GETTERS @XmlAttribute(name = "fbId") public String getFreebaseId() { return this.fbId; } @XmlElement(name = "firstName") public String getFirstName() { return this.firstName; } @XmlElement(name = "lastName") public String getLastName() { return this.lastName; } @XmlTransient public Collection<Performance> getPerformances() { return this.performances; } }

Each film has one (or many) directors and performances which are "Persons". I don't need a class for directors but I do for perfomances because they have more info.

Performance

@Entity @Table(name="performance") @XmlRootElement(name = "performace") public class Performance implements Serializable { @Id @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="film") private Film film; @Id @Column(name="film_character") private String character; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="actor") private Person actor; //TO STRING public String toString() { return this.actor.toString() + " - " + this.character; } //GETTERS @XmlTransient public Film getFilm() { return this.film; } @XmlElementRefs({ @XmlElementRef(name = "firstName", type = Person.class), @XmlElementRef(name = "lastName", type = Person.class) }) public Person getActor() { return this.actor; } @XmlElement(name = "character") public String getCharacter() { return this.character; } }

When I run this through JAXB I get this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <film fbId="1"> <description>Nice film</description> <person fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </person> <performace> <person fbId="4"> <firstName>Steve</firstName> <lastName>Buscemi</lastName> </person> <character>Billy</character> </performace> <performace> <person fbId="2"> <firstName>Jhon</firstName> <lastName>Travolta</lastName> </person> <character>Vincent</character> </performace> <performace> <person fbId="3"> <firstName>Samuel</firstName> <lastName>L Jackson</lastName> </person> <character>Jules</character> </performace> <performace> <person fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </person> <character>Jimmie</character> </performace> <title>Pulp Fiction</title> </film>

Is there a way to change the name of the "person"? To get something like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <film fbId="1"> <description>Nice film</description> <director fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> </director> <performace fbId="4"> <firstName>Steve</firstName> <lastName>Buscemi</lastName> <character>Billy</character> </performace> <performace fbId="2"> <firstName>Jhon</firstName> <lastName>Travolta</lastName> <character>Vincent</character> </performace> <performace fbId="3"> <firstName>Samuel</firstName> <lastName>L Jackson</lastName> <character>Jules</character> </performace> <performace fbId="1"> <firstName>Quentin</firstName> <lastName>Tarantino</lastName> <character>Jimmie</character> </performace> <title>Pulp Fiction</title> </film>

最满意答案

选项:

Make Director使用自己的@XmlRootElement扩展Person 使用JAXBElement<? extends Person> JAXBElement<? extends Person>而不是Person

问题是,@ XmlElementRef.name不适用于@XmlRootElement ,请在此处阅读:

如果type()是JAXBElement.class,则namespace()和name()指向带有XmlElementDecl的工厂方法。 XML元素名称是工厂方法的XmlElementDecl批注中的元素名称,或者如果在XML文档中替换了其替换组中的元素(其为head元素),则元素名称来自替换的XmlElementDecl元件。

如果type()不是JAXBElement.class,则XML元素名称是使用类型上的注释XmlRootElement与类型静态关联的XML元素名称。 如果类型未使用XmlElementDecl进行批注,那么这是一个错误。

如果type()不是JAXBElement.class,则此值必须为“”。

顺便一提

@XmlElementRefs({ @XmlElementRef(name = "firstName", type = Person.class), @XmlElementRef(name = "lastName", type = Person.class) })

对我来说似乎没有用。 @XmlElementRef不应映射目标类的属性。

Options:

Make Director extends Person with its own @XmlRootElement Use JAXBElement<? extends Person> instead of Person

The problem is, @XmlElementRef.name does not work for @XmlRootElement, read here:

If type() is JAXBElement.class , then namespace() and name() point to a factory method with XmlElementDecl. The XML element name is the element name from the factory method's XmlElementDecl annotation or if an element from its substitution group (of which it is a head element) has been substituted in the XML document, then the element name is from the XmlElementDecl on the substituted element.

If type() is not JAXBElement.class, then the XML element name is the XML element name statically associated with the type using the annotation XmlRootElement on the type. If the type is not annotated with an XmlElementDecl, then it is an error.

If type() is not JAXBElement.class, then this value must be "".

By the way

@XmlElementRefs({ @XmlElementRef(name = "firstName", type = Person.class), @XmlElementRef(name = "lastName", type = Person.class) })

does not seem valid to me. @XmlElementRef are not supposed to map properties of the target class.

更多推荐

本文发布于:2023-04-27 14:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1327152.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:象中   名称   如何在   JAXB   XmlRootElement

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!