javajaxbxjcxjb

JAXB property order


I have an XSD file. Using xjc I generate classes from it. How can I change the propOrder value from XmlType annotation in generated clases? I don't want to change XSD file as long as I am not an owner of it and I don't want to change classes generated from this schema. Is there any way to achieve this with custom binding file(xjb)? The problem is that propOrder value is not desirable for me. As a last solution I consider using parseMethod/printMethod for this class but this will be too tricky.

I am dealing with FpML(XML base format), here is an XSD element:

<xsd:complexType name="TradeIdentifier">
    <xsd:sequence>
        <xsd:choice>

            <xsd:sequence>
                <xsd:element name="issuer" type="IssuerId"></xsd:element>
                <xsd:element name="tradeId" type="TradeId"></xsd:element>
            </xsd:sequence>

            <xsd:sequence>
                <xsd:group ref="PartyAndAccountReferences.model">
                </xsd:group>
                <xsd:element name="reportingRole" type="ReportingRole" minOccurs="0"></xsd:element>
                <xsd:choice maxOccurs="unbounded">
                    <xsd:element name="tradeId" type="TradeId"></xsd:element>
                    <xsd:element name="versionedTradeId" type="VersionedTradeId"></xsd:element>
                </xsd:choice>
            </xsd:sequence>

        </xsd:choice>
    </xsd:sequence>
</xsd:complexType>

and here is propOrder:

@XmlType(name = "TradeIdentifier", propOrder = {
    "issuer",
    "tradeId",
    "partyReference",
    "accountReference",
    "reportingRole",
    "tradeIdOrVersionedTradeId"
})

when I set in object partyReference and tradeId, the generated xml is:

<partyTradeIdentifier>
    <tradeId>NONREF</tradeId>
    <partyReference href="Party2"/>
</partyTradeIdentifier>

which fails XSD verification with error:

[org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'tradeId'. One of '{"http://www.nsd.ru/repository/fpml-5.4":issuer, "http://www.nsd.ru/repository/fpml-5.4":partyReference}' is expected.]

The solution is to place partyReference element prior to tradeId. When I do it manually, everything works. But I don't want to change generated class manually, because in case of schema change I will have to repeat such manipulations. This is a way to hell.

I tried to rename one tradeId, so there would be two fields. But instead just one tradeId field is renamed and problem remains.


Solution

  • binding.xml

    Try generating the classes from your XML schema using the following binding file:

    <?xml version="1.0" encoding="UTF-8"?>
    <bindings xmlns="http://java.sun.com/xml/ns/jaxb" xmlns:xsi="http://www.w3.org/2000/10/XMLSchema-instance"
        xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
        xsi:schemaLocation="
    http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd"
        version="2.1">
        <globalBindings>
            <xjc:simple />
        </globalBindings>
    </bindings>
    

    XJC Call

    xjc -extension -b binding.xml schema.xsd