Forum Stats

  • 3,837,920 Users
  • 2,262,309 Discussions
  • 7,900,433 Comments

Discussions

XJC doesn't map or recognize when a restriction changes the type of one element within the base-clas

Hello,

I think this issue is kind of related to and some other discussions about restrictions/inheritance in here. I already solved the issue by applying the binding

<jaxb:globalBindings>
    <xjc:treatRestrictionLikeNewType/>
</jaxb:globalBindings>

while parsing my XSDs. But i have to find out if this is a problem in XJC/JAXB or whether the XSDs are somehow wrong.

I have the following XSD, which declares two abstract base-types: xink:Nachrichtenkopf.G2G and xink:Nachricht.G2G: http://www.osci.de/xinneres/basisnachricht/1/xinneres-basisnachricht.xsd

xink:Nachricht.G2G has an element of type xink:Nachrichtenkopf.G2G .

http://xpsw.domap.de/xpsw161/xpersonenstand-baukasten.xsd derives the two non-abstract types xpersonenstand:Nachricht.G2G and xpersonenstand:Nachrichtenkopf.G2G from these two abstact types via restriction.

Excerpt from http://xpsw.domap.de/xpsw161/xpersonenstand-baukasten.xsd :

...
<xs:complexType name="Nachricht.G2G">
    <xs:annotation>
        ...
    </xs:annotation>
    <xs:complexContent>
        <xs:restriction base="xink:Nachricht.G2G">
            <xs:sequence>
                <xs:element name="nachrichtenkopf" type="xpersonenstand:Nachrichtenkopf.G2G" form="unqualified">
                    <xs:annotation>
                        ...
                    </xs:annotation>
                </xs:element>
            </xs:sequence>
        ...
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>
...
<xs:complexType name="Nachrichtenkopf.G2G">
    <xs:annotation>
        <xs:documentation>Nachrichtenkopf für eine Nachricht zwischen zwei Akteuren, z. B. zwischen stamt und ab.</xs:documentation>
    </xs:annotation>
    <xs:complexContent>
        <xs:restriction base="xink:Nachrichtenkopf.G2G">
            ...
        </xs:restriction>
    </xs:complexContent>
</xs:complexType>
...

The restriction and declaration of xpersonenstand:Nachricht.G2G correctly references the non-abstract type xpersonenstand:Nachrichtenkopf.G2G with in a qualified manner with type="xpersonenstand:Nachrichtenkopf.G2G" in element "nachrichtenkopf", because the abstract type xint:Nachrichtenkopf.G2G which is used for element "nachrichtenkopf" in the declaration of xink:Nachricht.G2G cannot be instantiated.

Here is my first question: Is this a valid restriction in XML schema ? May the type of an element of the base-class be changed to a more concrete type in a restriction ?

If this is a valid restriction, then I wonder why JAXB ignores the type xpersonenstand:Nachrichtenkopf.G2G when generating the Class of xpersonenstand:Nachricht.G2G and uses the type abstract type xint:Nachrichtenkopf.G2G instead.

Class de\domap\xpsw\xpsw161\NachrichtG2G.java :

//
// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 generiert 
// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. 
// Generiert: 2015.07.15 um 01:32:39 PM CEST 
//


package de.domap.xpsw.xpsw161;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;


/**
 * Diese Klasse bildet die xpers-weite Basis für alle Nachrichtenköpfe. Sie dient der leichteren programmtechnischen Verarbeitung von Nachrichten. Außerdem enthält diese Klasse Informationen, die für jede Nachricht relevant sind. Dies sind im Einzelnen:
 * 
 * Angaben zur xpers-Version
 * Angaben über die zur Erstellung der Nachricht verwendete Software und deren Hersteller
 * eine optionale Angabe, ob es sich bei der Nachricht um eine Testnachricht handelt
 * eine optionale ID, die eine eindeutige Identifizierung der Nachricht ermöglicht.
 * 
 * <p>Java-Klasse für Nachricht.G2G complex type.
 * 
 * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
 * 
 * <pre>
 * &lt;complexType name="Nachricht.G2G">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.osci.de/xinneres/basisnachricht/1}Nachricht.G2G">
 *       &lt;sequence>
 *         &lt;element name="nachrichtenkopf" type="{http://xpsw.domap.de/xpsw161}Nachrichtenkopf.G2G" form="unqualified"/>
 *       &lt;/sequence>
 *       &lt;attribute name="produkt" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="produkthersteller" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="produktversion" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="standard" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" fixed="XPersonenstand" />
 *       &lt;attribute name="test" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="version" use="required" type="{http://xoev.de/latinchars/1_1/datatypes@}String.Latin" fixed="1.6.1" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Nachricht.G2G")
@XmlSeeAlso({
    NachrichtStA2StA.class,
    StA2StatAbschluss055010 .class,
    NachrichtStA2Stat.class
})
public class NachrichtG2G
    extends de.osci.xinneres.basisnachricht._1.NachrichtG2G
{


}

The base class de\osci\xinneres\basisnachricht\_1\NachrichtG2G.java :

//
// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 generiert 
// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. 
// Generiert: 2015.07.15 um 01:32:39 PM CEST 
//


package de.osci.xinneres.basisnachricht._1;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;


/**
 * Dieser Typ realisiert die abstrakte Oberklasse für alle Nachrichten zwischen Behörden und anderen (öffentlichen) Stellen. Jede in den Fachstandards definierte konkrete Nachricht erbt von diesem Typ. Auf diese Weise wird für alle Nachrichten der Fachstandards eine einheitliche Grundstruktur gewährleistet.
 * Der Zusatz G2G ist die Abkürzung für den Begriff  government-to-government, also die Kommunikation zwischen staatlichen Einrichtungen.
 * 
 * <p>Java-Klasse für Nachricht.G2G complex type.
 * 
 * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
 * 
 * <pre>
 * &lt;complexType name="Nachricht.G2G">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="nachrichtenkopf" type="{http://www.osci.de/xinneres/basisnachricht/1}Nachrichtenkopf.G2G" form="unqualified"/>
 *       &lt;/sequence>
 *       &lt;attribute name="produkt" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="produkthersteller" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="produktversion" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="standard" use="required" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="test" type="{http://xoev.de/latinchars/1_1/datatypes}String.Latin" />
 *       &lt;attribute name="version" use="required" type="{http://xoev.de/latinchars/1_1/datatypes@}String.Latin" />
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Nachricht.G2G", propOrder = {
    "nachrichtenkopf"
})
@XmlSeeAlso({
    de.domap.xpsw.xpsw161.NachrichtG2G.class
})
public abstract class NachrichtG2G {

    @XmlElement(required = true)
    protected NachrichtenkopfG2G nachrichtenkopf;
    @XmlAttribute(name = "produkt", required = true)
    protected String produkt;
    @XmlAttribute(name = "produkthersteller", required = true)
    protected String produkthersteller;
    @XmlAttribute(name = "produktversion")
    protected String produktversion;
    @XmlAttribute(name = "standard", required = true)
    protected String standard;
    @XmlAttribute(name = "test")
    protected String test;
    @XmlAttribute(name = "version", required = true)
    protected String version;

    /**
     * Ruft den Wert der nachrichtenkopf-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link NachrichtenkopfG2G }
     *     
     */
    public NachrichtenkopfG2G getNachrichtenkopf() {
        return nachrichtenkopf;
    }

    /**
     * Legt den Wert der nachrichtenkopf-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link NachrichtenkopfG2G }
     *     
     */
    public void setNachrichtenkopf(NachrichtenkopfG2G value) {
        this.nachrichtenkopf = value;
    }

    /**
     * Ruft den Wert der produkt-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getProdukt() {
        return produkt;
    }

    /**
     * Legt den Wert der produkt-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setProdukt(String value) {
        this.produkt = value;
    }

    /**
     * Ruft den Wert der produkthersteller-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getProdukthersteller() {
        return produkthersteller;
    }

    /**
     * Legt den Wert der produkthersteller-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setProdukthersteller(String value) {
        this.produkthersteller = value;
    }

    /**
     * Ruft den Wert der produktversion-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getProduktversion() {
        return produktversion;
    }

    /**
     * Legt den Wert der produktversion-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setProduktversion(String value) {
        this.produktversion = value;
    }

    /**
     * Ruft den Wert der standard-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getStandard() {
        return standard;
    }

    /**
     * Legt den Wert der standard-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setStandard(String value) {
        this.standard = value;
    }

    /**
     * Ruft den Wert der test-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getTest() {
        return test;
    }

    /**
     * Legt den Wert der test-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setTest(String value) {
        this.test = value;
    }

    /**
     * Ruft den Wert der version-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link String }
     *     
     */
    public String getVersion() {
        return version;
    }

    /**
     * Legt den Wert der version-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link String }
     *     
     */
    public void setVersion(String value) {
        this.version = value;
    }

}

So here my second question: Isn't de.domap.xpsw.xpsw161.NachrichtG2G supposed to overwrite the member-variable nachrichtenkopf using type de.domap.xpsw.xpsw161.NachrichtenkopfG2G instead of just inheriting it from de.osci.xinneres.basisnachricht._1.NachrichtG2G with type de.osci.xinneres.basisnachricht._1.NachrichtenkopfG2G ?

For completeness i'll give you the two generated classes of NachrichtenkopfG2G too:

Class de\domap\xpsw\xpsw161\NachrichtenkopfG2G.java:

//
// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 generiert 
// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. 
// Generiert: 2015.07.15 um 01:32:39 PM CEST 
//


package de.domap.xpsw.xpsw161;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlType;


/**
 * Nachrichtenkopf für eine Nachricht zwischen zwei Akteuren, z. B. zwischen stamt und ab.
 * 
 * <p>Java-Klasse für Nachrichtenkopf.G2G complex type.
 * 
 * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
 * 
 * <pre>
 * &lt;complexType name="Nachrichtenkopf.G2G">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.osci.de/xinneres/basisnachricht/1}Nachrichtenkopf.G2G">
 *       &lt;sequence>
 *         &lt;element name="identifikation.nachricht" type="{http://xpsw.domap.de/xpsw161}Identifikation.Nachricht" form="unqualified"/>
 *         &lt;element name="leser" type="{http://www.osci.de/xinneres/behoerde/1}Behoerde" form="unqualified"/>
 *         &lt;element name="autor" type="{http://www.osci.de/xinneres/behoerde/1@}Behoerde.Erreichbar" form="unqualified"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Nachrichtenkopf.G2G")
public class NachrichtenkopfG2G
    extends de.osci.xinneres.basisnachricht._1.NachrichtenkopfG2G
{


}

Class de\osci\xinneres\basisnachricht\_1\NachrichtenkopfG2G.java:

//
// Diese Datei wurde mit der JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.7 generiert 
// Siehe <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a> 
// Änderungen an dieser Datei gehen bei einer Neukompilierung des Quellschemas verloren. 
// Generiert: 2015.07.15 um 01:32:39 PM CEST 
//


package de.osci.xinneres.basisnachricht._1;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlSeeAlso;
import javax.xml.bind.annotation.XmlType;
import de.osci.xinneres.behoerde._1.Behoerde;
import de.osci.xinneres.behoerde._1.BehoerdeErreichbar;


/**
 * Nachrichtenkopf für Nachrichten zwischen Behörden und anderen (öffentlichen) Stellen.
 * 
 * <p>Java-Klasse für Nachrichtenkopf.G2G complex type.
 * 
 * <p>Das folgende Schemafragment gibt den erwarteten Content an, der in dieser Klasse enthalten ist.
 * 
 * <pre>
 * &lt;complexType name="Nachrichtenkopf.G2G">
 *   &lt;complexContent>
 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
 *       &lt;sequence>
 *         &lt;element name="identifikation.nachricht" type="{http://www.osci.de/xinneres/basisnachricht/1}Identifikation.Nachricht" form="unqualified"/>
 *         &lt;element name="leser" type="{http://www.osci.de/xinneres/behoerde/1}Behoerde" form="unqualified"/>
 *         &lt;element name="autor" type="{http://www.osci.de/xinneres/behoerde/1@}Behoerde.Erreichbar" form="unqualified"/>
 *       &lt;/sequence>
 *     &lt;/restriction>
 *   &lt;/complexContent>
 * &lt;/complexType>
 * </pre>
 * 
 * 
 */
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "Nachrichtenkopf.G2G", propOrder = {
    "identifikationNachricht",
    "leser",
    "autor"
})
@XmlSeeAlso({
    de.domap.xpsw.xpsw161.NachrichtenkopfG2G.class
})
public abstract class NachrichtenkopfG2G {

    @XmlElement(name = "identifikation.nachricht", required = true)
    protected IdentifikationNachricht identifikationNachricht;
    @XmlElement(required = true)
    protected Behoerde leser;
    @XmlElement(required = true)
    protected BehoerdeErreichbar autor;

    /**
     * Ruft den Wert der identifikationNachricht-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link IdentifikationNachricht }
     *     
     */
    public IdentifikationNachricht getIdentifikationNachricht() {
        return identifikationNachricht;
    }

    /**
     * Legt den Wert der identifikationNachricht-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link IdentifikationNachricht }
     *     
     */
    public void setIdentifikationNachricht(IdentifikationNachricht value) {
        this.identifikationNachricht = value;
    }

    /**
     * Ruft den Wert der leser-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link Behoerde }
     *     
     */
    public Behoerde getLeser() {
        return leser;
    }

    /**
     * Legt den Wert der leser-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link Behoerde }
     *     
     */
    public void setLeser(Behoerde value) {
        this.leser = value;
    }

    /**
     * Ruft den Wert der autor-Eigenschaft ab.
     * 
     * @return
     *     possible object is
     *     {@link BehoerdeErreichbar }
     *     
     */
    public BehoerdeErreichbar getAutor() {
        return autor;
    }

    /**
     * Legt den Wert der autor-Eigenschaft fest.
     * 
     * @param value
     *     allowed object is
     *     {@link BehoerdeErreichbar }
     *     
     */
    public void setAutor(BehoerdeErreichbar value) {
        this.autor = value;
    }

}

When unmarshalling a XML-Dokument of type xpersonenstand:Nachricht.G2G with the above "wrong" class de\domap\xpsw\xpsw161\NachrichtG2G.java, this of course results in the following error, because the unmarshaller tries to instantiate the member-variable nachrichtenkopf with the abstract type de.osci.xinneres.basisnachricht._1.NachrichtenkopfG2G :

JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException: Unable to create an instance of de.osci.xinneres.basisnachricht._1.NachrichtenkopfG2G
 - with linked exception:
[java.lang.InstantiationException]
    org.springframework.oxm.jaxb.Jaxb2Marshaller.convertJaxbException(Jaxb2Marshaller.java:884)
    org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:758)
    org.springframework.oxm.jaxb.Jaxb2Marshaller.unmarshal(Jaxb2Marshaller.java:735)
...
Caused by: Unable to create an instance of de.osci.xinneres.basisnachricht._1.NachrichtenkopfG2G
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.handleEvent(UnmarshallingContext.java:726)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.Loader.reportError(Loader.java:247)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.createInstance(UnmarshallingContext.java:690)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.StructureLoader.startElement(StructureLoader.java:171)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiTypeLoader.startElement(XsiTypeLoader.java:65)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext._startElement(UnmarshallingContext.java:559)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.startElement(UnmarshallingContext.java:538)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.startElement(SAXConnector.java:153)
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)
    com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.scanStartElement(XMLNSDocumentScannerImpl.java:379)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2786)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:606)
    com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:117)
    com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:510)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:848)
    com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:777)
    com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)
    com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:243)
    com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:214)
    javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:140)
    javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:123)
    ...

Regards and mille grazie in advance,

Alex

This discussion has been closed.