Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shared class for child element in JAXB in different xmls/roots

Tags:

java

xml

jaxb

In JAXB when using automatic class generation via xjc from xsd scheme.

alpha.xsd

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="alpha">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="persons">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="person" maxOccurs="unbounded" minOccurs="0">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="name"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

beta.xml

<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="country">
    <xs:complexType>
      <xs:sequence>
        <xs:element name="class">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="person">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element type="xs:string" name="name"/>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

As you can see there is Person element which is shared among these two schemes. What I would like to do is:

  • generate classes using xjc in a way that ObjectFactory class is shared for both schema classes (the output classes will be in one package)
  • not use nested static classes (with attribute localScoping="toplevel")
  • use Person class to bind with /alpha/persons/person as with /country/class/person so there are not two Person classes created

The purpose of this is unmarshalling one xml, applying business logic and creating another one as output where some elements (like Person) are same and shared for both xml files. The namespace will be the same for both files.

I would welcome if you can present me with complete .xjb bindings settings file. So far mine contains only:

<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 localScoping="toplevel"/>
</jxb:bindings>

And of course I get name collision error as I do not know how to set binding compiler to see Person as the same entity/element.

like image 490
ps-aux Avatar asked Mar 21 '23 18:03

ps-aux


2 Answers

You can use an external binding file to indicate that during class generation we wish to use our existing class for the complex type called Document.

binding.xml

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

    <jxb:bindings schemaLocation="beta.xsd">
        <jxb:bindings node="//xs:element[@name='person']/complexType">
            <jxb:class ref="alpha.Person"/>
        </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>

XJC Call

xjc -b binding.xml beta.xsd
like image 154
bdoughan Avatar answered Apr 07 '23 13:04

bdoughan


If namespace of person from A will be equals namespace person from B, that xjc has to generate the correct classes.

like image 45
Sergey Morozov Avatar answered Apr 07 '23 14:04

Sergey Morozov