How do you customize how JAXB generates plural method names?

27,905

Solution 1

By default the following is generated for your schema fragment:

    import java.util.ArrayList;
    import java.util.List;
    import javax.xml.bind.annotation.XmlAccessType;
    import javax.xml.bind.annotation.XmlAccessorType;
    import javax.xml.bind.annotation.XmlElement;
    import javax.xml.bind.annotation.XmlType;

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "physicianList", propOrder = {
        "physician"
    })
    public class PhysicianList {

        @XmlElement(name = "Physician")
        protected List<Physician> physician;

        public List<Physician> getPhysician() {
            if (physician == null) {
                physician = new ArrayList<Physician>();
            }
            return this.physician;
        }

    }

If you annotate your XML schema:

    <xs:schema
        xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        jaxb:version="2.1">

        <xs:complexType name="physician">
            <xs:sequence>
            </xs:sequence>
        </xs:complexType>

        <xs:complexType name="physicianList">
            <xs:sequence>
                <xs:element name="Physician"
                            type="physician"
                            minOccurs="0"
                            maxOccurs="unbounded">
                      <xs:annotation>
                          <xs:appinfo>
                              <jaxb:property name="physicians"/>
                          </xs:appinfo>
                      </xs:annotation>
                 </xs:element>
            </xs:sequence>
        </xs:complexType>

    </xs:schema>

Then you can generate the desired class:

import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlType;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "physicianList", propOrder = {
    "physicians"
})
public class PhysicianList {

    @XmlElement(name = "Physician")
    protected List<Physician> physicians;

    public List<Physician> getPhysicians() {
        if (physicians == null) {
            physicians = new ArrayList<Physician>();
        }
        return this.physicians;
    }

}

Solution 2

Maybe it's a little late to answer, but there's another way to generate plural names simply, without mixing XML Schema and JAXB Bindings.

By using JAXB XJC binding compiler with the "-extension" mode. A customization bindings file need to be added, like this one :

<?xml version="1.0"?>
<jxb:bindings version="1.0"
              xmlns:jxb="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"
              jxb:extensionBindingPrefixes="xjc">

  <jxb:globalBindings>              
    <xjc:simple/>
  </jxb:globalBindings>

</jxb:bindings>

References :

Share:
27,905
SingleShot
Author by

SingleShot

Software Engineer. Wargamer.

Updated on November 05, 2020

Comments

  • SingleShot
    SingleShot over 3 years

    We are using JAXB to generate Java classes and have encountered a few cases where generated plural method names are not correct. For example, where we expect getPhysicians we are getting getPhysicien. How would we customize how JAXB pluralizes specific methods?

    The schema:

    <xs:complexType name="physician">
        <xs:sequence>
           ...
        </xs:sequence>
    </xs:complexType>
    
    <xs:complexType name="physicianList">
        <xs:sequence>
            <xs:element name="Physician"
                        type="physician"
                        minOccurs="0"
                        maxOccurs="unbounded"/>
        </xs:sequence>
    </xs:complexType>
    

    The generated Java code:

    ...
    public class PhysicianList {
    ...
    
        @XmlElement(name = "Physician")
        protected List<Physician> physicien;
        ...
    
        public List<Physician> getPhysicien() {
            if (physicien == null) {
                physicien = new ArrayList<Physician>();
            }
            return this.physicien;
        }
    

    Update

    This has been answered by Blaise. However, I prefer not mixing concerns such as JAXB customizations in an XML schema. So for those of you with the same preference, here is a JAXB binding file that achieves the same thing as what Blaise suggested, keeping JAXB customization out of the schema:

    <jaxb:bindings xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                   xmlns:xs="http://www.w3.org/2001/XMLSchema"
                   version="2.0">
    
        <jaxb:bindings schemaLocation="myschema.xsd">
            <jaxb:bindings node="//xs:complexType[@name='physicianList']//xs:element[@name='Physician']">
                <jaxb:property name="physicians"/>
            </jaxb:bindings>
        </jaxb:bindings>
    
    </jaxb:bindings>
    
  • SingleShot
    SingleShot over 13 years
    That worked great. Thanks! FYI, I dislike mixing concerns such as JAXB customizations in an XML schema, so I've added to the end of my question an example of using a binding file to do the same as you suggest. Thanks again!
  • Ashish Kumar Shah
    Ashish Kumar Shah almost 8 years
    I tried the solution suggested by you, and the classes generated still dont have the return types I would love to have. I have asked another question for that here. I would really appreciate your help if you take your time to answer this question as well.