JAXB schema to Java Different XmlRootElement name and Class name
Asked Answered
L

1

6

I have a xsd schema from which I'm generating some java classes. I'm using jaxb for the generation.

I want to be able to generate a class annotated with @XmlRootElement, but I want the @XmlRootElement name property to be different than the name of the generated class.

In my xsd I'm defining the following:

<xs:element name="customer">
    <xs:complexType>
        <xs:sequence>
         ....
        </xs:sequence>
     </xs:complexType>
</xs:element>

This piece of code generates the following java class:

@XmlRootElement(name = "customer")
public class Customer {
...
}

The name property of the @XmlRootElement is the same as the name of the generated Class. I want the generated class name to be CustomerRequest.

I've tryed to use the jaxb:class definition to change the classe name. Indeed this option changes the class name but removes the @XmlRootElement annotation, and I need it to be present.

The following xsd:

<xs:element name="customer">
    <xs:complexType>
        <xs:annotation>
                <xs:appinfo>
                    <jaxb:class name="CustomerRequest"/>
                </xs:appinfo>
            </xs:annotation>
        <xs:sequence>
        </xs:sequence>
    </xs:complexType>
</xs:element>

Generates this class:

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "customer", propOrder = {

})
public class CustomerRequest {
}

How can I make the property name of the @XmlRootElement annotation different from the generated class name without loosing the annotation?

Solution update: User Xstian proposed the correct solution using external bindings. Just for further reference, I'll update my own post with the solution converted for using inline bindings:

 <xs:element name="customer">
        <xs:complexType>
            <xs:annotation>
                <xs:documentation>Request object for the operation that checks if a customer profile exists.</xs:documentation>
                <xs:appinfo>
                        <annox:annotate>
                            <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement" name="customer"/>
                        </annox:annotate>
                        <jaxb:class name="CustomerRequest"/>
                    </xs:appinfo>
                </xs:annotation>
            <xs:sequence>
            </xs:sequece>
    </xs:complexType>
</xs:element>
Lour answered 24/10, 2014 at 8:57 Comment(1)
You can now use Java syntax in the JAXB2 Annotate Plugin. Something like @javax.xml.bind.annotation.XmlRootElement( name="customer", namespace="yourNamespaceIfYouWant") should work instead of the inner annox:annotate element. (I'm the author.)Ooze
R
8

I suggest you to use this bindings

<bindings version="2.0" xmlns="http://java.sun.com/xml/ns/jaxb"
    xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
    xmlns:annox="http://annox.dev.java.net"
    xmlns:namespace="http://jaxb2-commons.dev.java.net/namespace-prefix">
    <bindings schemaLocation="../your.xsd">

        <bindings node="//xs:element[@name='customer']//xs:complexType">
            <annox:annotate>
                <annox:annotate annox:class="javax.xml.bind.annotation.XmlRootElement"
                    name="customer" namespace="yourNamespaceIfYouWant">
                </annox:annotate>
            </annox:annotate>
            <class name="CustomerRequest"/>
        </bindings>

    </bindings>
</bindings>

Class

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "header"
})
@XmlRootElement(name = "customer", namespace = "yourNamespaceIfYouWant")
public class CustomerRequest
Regelate answered 24/10, 2014 at 9:52 Comment(6)
You can now use Java syntax in the JAXB2 Annotate Plugin. Something like @javax.xml.bind.annotation.XmlRootElement( name="customer", namespace="yourNamespaceIfYouWant") should work instead of the inner annox:annotate element.Ooze
Hmm I see, you use annox to inject the annotation in the class. That might work, but seems tricky :p I'll try your solution with the external binding you posted and with the internal bindingsLour
I prefer external binding to make clear and java\JAXB independent the XSD.Regelate
I agree with the separation between java/jaxb, but for this specific case I don't want to handle xpath expression in order to use the external bindings match by node. Your solution works and I will update my post with the inline bindings solution too just for reference. thksLour
@Ooze because we are injecting the annotation XmlRootElement, that was suppose to be generated for each <element> defined in the schema since these elements aren't suppose to be reused.Lour
I used part of your solution using <class> tag to make work my importFloria

© 2022 - 2024 — McMap. All rights reserved.