Nhano
Nhano

Reputation: 645

JAXB element showing the SuperClass name and the Class name as an attribute

I'm trying to serialize in XML some objects using JAXB, and when I get to a field being an abstract Class pointer, I get this code serialized:

<Message>
    <MessageID>1</MessageID>
    <OperationType>Update</OperationType>
    **<Content xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="product">**
        <SKU>skuparent</SKU> ...

But what I would need is like:

<Message>
    <MessageID>1</MessageID>
    <OperationType>Update</OperationType>
    **<Product>**
        <SKU>skuparent</SKU>

And I don't get to transform it using "@XMLTransient" tagging, that's the only proposition I got from the other posts

My code is this:

@XmlType(propOrder = { "MessageID", "operationType", "Content"})
public static class message{
    public int MessageID;
    private String OperationType;
    @XmlElement(name ="OperationType")
    public String getOperationType() {
        return OperationType;
    }

    public void setOperationType(String _operationType) {
        OperationType = operationType.valueOf(_operationType).toString();
    }

    public AmazonContent Content;
}

Where "AmazonContent" is an Abstract Class like that:

@XmlSeeAlso({Product.class})
public abstract class AmazonContent {

}

and the subClass instance is:

@XmlRootElement(name = "Product")
@XmlType(propOrder = { "SKU", "StandardProductID", "DescriptionData", "ProductData"})
public class Product extends AmazonContent {

any ideas?

Upvotes: 2

Views: 1063

Answers (2)

Nhano
Nhano

Reputation: 645

A detail Blaise Doughan missed possibly due to later updates of the Api, and I found here:

http://old.nabble.com/Re:-XmlElementRef-points-to-a-non-existent-class-p22366506.html

The XmlReference should be parametrized as follows

The abstract class is pointedhere:

public static class productData{
    @XmlElementRefs({
        @XmlElementRef(type = Shoes.class),
        @XmlElementRef(type = Clothing.class)
    })
    public AmazonProductData Product; //Abstract AmazonProductData
}

and these are the SubClasses:

@XmlRootElement(name = "Shoes")
public class Shoes extends AmazonProductData {

and

@XmlRootElement(name = "Clothing")
public class Clothing extends AmazonProductData {

nothing else needed, nor @XmlTransient, nor @XmlSeeAlso or anything

hope it helps!

Upvotes: 0

bdoughan
bdoughan

Reputation: 149017

By default a JAXB implementation will leverage the xsi:type attribute as the descriminator node when representing inheritance:

Using the element name as the inheritance indicator corresponds to the XML schema concept of substitution groups which can be mapped with the @XmlElementRef annotation. The element name for the value will be what was specified on the @XmlRootElement annotation on the reference class.

@XmlElementRef
public AmazonContent Content;

For more information:

Upvotes: 1

Related Questions