How to use JAXB to process messages from two separate schemas (with the same rootelement name)

We have a client that sends xml messages created from two separate schemes.

We would like to process them in one application, as the content is connected.

We cannot change the client schema that they use to create XML messages ...

We can modify our own copies of two schemes (or binding.jxb) - if that helps - so that our JAXB message processing is created from two separate schemes.

Unfortunately, both schemes have the same root element name (see below).

QUESTION: Is JAXB absolutely prohibiting the processing of two schemes that have the same root element name?

- If so, I will stop my Easter egg hunt to solve this ... --- Or is there some workaround that will allow us to use JAXB to process these XML messages created from two different schemes?

schema1 (note the name of the root element: "A"):

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">
    <xsd:element name="A">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="AA">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="AAA1" type="xsd:string" />
                            <xsd:element name="AAA2" type="xsd:string" />
                            <xsd:element name="AAA3" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="BB">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="BBB1" type="xsd:string" />
                            <xsd:element name="BBB2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>

schema2 (note, again, using the same root element name: "A")

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">
    <xsd:element name="A">
        <xsd:complexType>
            <xsd:sequence>
                <xsd:element name="CCC">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="DDD1" type="xsd:string" />
                            <xsd:element name="DDD2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="EEE">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="EEE1">
                                <xsd:complexType>
                                    <xsd:sequence>
                                        <xsd:element name="FFF1" type="xsd:string" />
                                        <xsd:element name="FFF2" type="xsd:string" />
                                    </xsd:sequence>
                                </xsd:complexType>
                            </xsd:element>
                            <xsd:element name="EEE2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
            </xsd:sequence>
        </xsd:complexType>
    </xsd:element>
</xsd:schema>
+3
source share
3 answers

QUESTION: Does JAXB absolutely forbid the processing of two schemes that have the same root element name?

ANSWER: , , unmarshal.

A1

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="A")
public class A1 {    
}

A2

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement(name="A")
public class A2 {    
}

Input.xml

<A/>

Demo

import java.io.File;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import javax.xml.transform.stream.StreamSource;

public class Demo {

    public static void main(String[] args) throws Exception {
        JAXBContext jc = JAXBContext.newInstance(A1.class, A2.class);

        Unmarshaller unmarshaller = jc.createUnmarshaller();
        File xmlFile = new File("input.xml");
        StreamSource xmlSource = new StreamSource(xmlFile);
        A1 a1 = unmarshaller.unmarshal(xmlSource, A1.class).getValue();

        Marshaller marshaller = jc.createMarshaller();
        marshaller.marshal(a1, System.out);
    }
}

:


, , . . - XJC?

<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="schema1.xsd">
            <jxb:bindings node="//xs:element[@name='A']">
                <jxb:class name="RenamedA"/>
            </jxb:bindings>
    </jxb:bindings>
</jxb:bindings>
+1

( ), .

(: " ", , )

, , , ( ) ( , ...) schema1 schema2 " )...

schemacombo.xsd:

<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" elementFormDefault="qualified">
    <xs:group name="schema1">
        <xs:sequence>
            <xs:element name="AA">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="CC1" type="xs:string"/>
                        <xs:element name="CC2" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="BB">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="DD1" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
          </xs:sequence>   
    </xs:group>
    <xs:group name="schema2">
        <xs:sequence>
            <xs:element name="AA">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="CC1" type="xs:string"/>
                        <xs:element name="CC2" type="xs:string"/>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
            <xs:element name="BB">
                <xs:complexType>
                    <xs:sequence>
                        <xs:element name="DD1">
                            <xs:complexType>
                                <xs:sequence>
                                    <xs:element name="EE1" type="xs:string"/>
                                    <xs:element name="EE2" type="xs:string"/>
                                </xs:sequence>
                            </xs:complexType>
                        </xs:element>
                    </xs:sequence>
                </xs:complexType>
            </xs:element>
        </xs:sequence>
    </xs:group>
    <xs:element name="A">
        <xs:complexType>
            <xs:choice>
                <xs:group ref="schema1" />
                <xs:group ref="schema2" />
            </xs:choice>
        </xs:complexType>
    </xs:element>    
</xs:schema>

xjc schemacombo.xsd -b binding.xjb

... binding.xjb

<?xml version="1.0" encoding="UTF-8"?>
<jxb:bindings xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
               xmlns:xs="http://www.w3.org/2001/XMLSchema"
               jaxb:version="2.0">

    <jxb:bindings schemaLocation = "schemacombo.xsd" node="/xs:schema">>
      <jxb:schemaBindings>
        <jxb:bindings node="xs:group[@name='schema2']">
            <jxb:nameXmlTransform>
                <jxb:modelGroupName suffix="2"/>
            </jxb:nameXmlTransform>         
        </jxb:bindings>
        </jxb:schemaBindings>
    </jxb:bindings>

</jxb:bindings>

...- , , ... , :

parsing a schema...
[ERROR] cos-element-consistent: Error for type '#AnonType_A'. Multiple elements with name 'AA', with different types, appear in the model group.
  line 49 of file:/C:/AAAAA_delegate/schemacombo.xsd

[ERROR] cos-nonambig: AA and AA (or elements from their substitution group) violate "Unique Particle Attribution". During validation against this schema, ambiguity would be created for those two particles.
  line 49 of file:/C:/AAAAA_delegate/schemacombo.xsd

Failed to parse a schema.

, . - , , .

+1

, , , - . , .

, , , , , :

<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    elementFormDefault="qualified">

<xsd:group name="schema1a">
        <xsd:sequence>
            <xsd:element name="AA">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="AAA1" type="xsd:string" />
                        <xsd:element name="AAA2" type="xsd:string" />
                        <xsd:element name="AAA3" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
            <xsd:element name="BB">
                <xsd:complexType>
                    <xsd:sequence>
                        <xsd:element name="BBB1" type="xsd:string" />
                        <xsd:element name="BBB2" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>

<xsd:group name="schema2a">
            <xsd:sequence>
                <xsd:element name="CCC">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="DDD1" type="xsd:string" />
                            <xsd:element name="DDD2" type="xsd:string" />
                        </xsd:sequence>
                    </xsd:complexType>
                </xsd:element>
                <xsd:element name="EEE">
                    <xsd:complexType>
                        <xsd:sequence>
                            <xsd:element name="EEE1">
                                <xsd:complexType>
                                    <xsd:sequence>
                                        <xsd:element name="FFF1" type="xsd:string" />
                                        <xsd:element name="FFF2" type="xsd:string" />
                                    </xsd:sequence>
                                </xsd:complexType>
                            </xsd:element>
                        <xsd:element name="EEE2" type="xsd:string" />
                    </xsd:sequence>
                </xsd:complexType>
            </xsd:element>
        </xsd:sequence>
    </xsd:group>
    <xsd:element name="A">
    <xsd:complexType>
        <xsd:choice>
            <xsd:group ref="schema1a" />
            <xsd:group ref="schema2a" />
        </xsd:choice>
    </xsd:complexType>
    </xsd:element>
</xsd:schema>

essentially, we take complex type definitions for each element of the scheme and change them to a group definition, then we include these group definitions in the selection element. this will effectively allow the jaxb parser to correctly process documents that are created using any scheme. it is a lot of work to maintain this between updates of any scheme .. but maybe it can be automated using XSLT and some scripts.

hope this helps

0
source

All Articles