Forum Stats

  • 3,839,329 Users
  • 2,262,481 Discussions
  • 7,900,934 Comments

Discussions

jaxb unmarshalling problem

GeertsP-JavaNet
GeertsP-JavaNet Member Posts: 14
edited Dec 1, 2015 3:54PM in Java Technology & XML

Hi all,

  being new to JAXB in Java I am trying to get a (trivial) parsing of an XML file into a java object but I am completely stuck.

Since I can't find any way to attach files (can someone enlighten me on this please) I will do this inline :

I have the following xsd:

------------------------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>

<!--

Deze XSD beschrijft de berichten die naar de LoggingService gestuurd kunnen worden.

Bij het maken van deze XSD is uitgegaan van de eisen en mogelijkheden van het BHS systeem in plaats van het definieren

van een generieke interface. Dit om te voorkomen dat applicatie meldingen kunnen worden afgekeurd ondanks dat deze

aan de XSD voldoen. Aangezien de LoggingService onderdeel is van de infrastructuur van de ESB moet deze zo robuust

mogelijk zijn.

Bij het opstellen van deze XSD is gebruik gemaakt van BHS-IRS v2.10 en BHS-IDD-APPL v3.8, interface I5-1.

-->

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

     xmlns:am="http://www.prorail.nl/Prorail/ApplicatieMelding"

     targetNamespace="http://www.prorail.nl/Prorail/ApplicatieMelding"

     elementFormDefault="unqualified"

     attributeFormDefault="unqualified">

    <xsd:element name="Applicatiemelding" type="am:ApplicatiemeldingType"/>

    <xsd:complexType name="ApplicatiemeldingType">

        <xsd:sequence>

            <xsd:element name="SysteemId" type="am:SysteemIdType"/>

            <xsd:element name="Timestamp" type="am:TimestampType"/>

            <xsd:element name="ApplicatieInstantie" type="am:ApplicatieInstantieType"/>

            <xsd:element name="ApplicatieVerkorting" type="am:ApplicatieVerkortingType"/>

            <xsd:element name="ProcesId" type="am:ProcesIdType"/>

            <xsd:element name="FunctieId" type="am:FunctieIdType"/>

            <xsd:element name="SeverityCode" type="am:SeverityCodeType"/>

            <xsd:element name="MeldingNummer" type="am:MeldingNummerType"/>

            <xsd:element name="MeldingTekst" type="am:MeldingTekstType"/>

            <xsd:element name="Component" type="am:ComponentType"/>

            <xsd:element name="ComponentToestand" type="am:ComponentToestandType"/>

        </xsd:sequence>

    </xsd:complexType>

    <xsd:simpleType name="SysteemIdType">

        <xsd:annotation>

            <xsd:documentation>Systeemnaam waar de melding betrekking op heeft.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="50"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="TimestampType">

        <xsd:annotation>

            <xsd:documentation>Moment waarop de verstoring is opgetreden.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:dateTime"/>

    </xsd:simpleType>

    <xsd:simpleType name="ApplicatieInstantieType">

        <xsd:annotation>

            <xsd:documentation>Een unieke aanduiding voor de applicatie indien deze applicatie tegelijkertijd meerdere malen actief is op een systeem.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="8"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="ApplicatieVerkortingType">

        <xsd:annotation>

            <xsd:documentation>Unieke applicatie naam afkorting.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string"/>

    </xsd:simpleType>

    <xsd:simpleType name="ProcesIdType">

        <xsd:annotation>

            <xsd:documentation>De proces id.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="8"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="FunctieIdType">

        <xsd:annotation>

            <xsd:documentation>De functie naam.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="8"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="SeverityCodeType">

        <xsd:annotation>

            <xsd:documentation>Aanduiding van de ernst van de melding.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:enumeration value="INFO"/>

            <xsd:enumeration value="WARN"/>

            <xsd:enumeration value="ERROR"/>

            <xsd:enumeration value="FATAL"/>

            <xsd:enumeration value="SUCCESS"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="MeldingNummerType">

        <xsd:annotation>

            <xsd:documentation>Uniek nummer voor het type fout.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:integer">

            <xsd:totalDigits value="25"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="MeldingTekstType">

        <xsd:annotation>

            <xsd:documentation>Vrije tekst met omschrijving melding.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="50"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="ComponentType">

        <xsd:annotation>

            <xsd:documentation>De unieke identificatie van b.v. een infra element bericht of transactie.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:string">

            <xsd:maxLength value="25"/>

        </xsd:restriction>

    </xsd:simpleType>

    <xsd:simpleType name="ComponentToestandType">

        <xsd:annotation>

            <xsd:documentation>De toestand van het component. Zie BHS-IDD-APPL voor de betekenis van deze waarden en gerelateerde severity codes.</xsd:documentation>

        </xsd:annotation>

        <xsd:restriction base="xsd:integer">

            <xsd:enumeration value="0"/>

            <xsd:enumeration value="1"/>

            <xsd:enumeration value="2"/>

            <xsd:enumeration value="3"/>

            <xsd:enumeration value="4"/>

            <xsd:enumeration value="5"/>

            <xsd:enumeration value="6"/>

            <xsd:enumeration value="7"/>

            <xsd:enumeration value="8"/>

            <xsd:enumeration value="9"/>

        </xsd:restriction>

    </xsd:simpleType>

</xsd:schema>

------------------------------------------------------------------- 

I have processed this with xjc and get the following 4 java files

- ApplicatieMeldingType.java

- ObjectFactory.java

- package-info.java

- SeverityCodeType.java

My main (test) code looks something like this :

-----------------------------------------------------------------------------

public class ParseApplicatieMelding {

    void run() {

        try {

            File file = new File("c:/data/ApplicatieMelding.xml");

          

            JAXBContext jaxbContext = JAXBContext.newInstance(ObjectFactory

                    .createApplicatiemelding());

            Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

            ApplicatiemeldingType Applicatiemelding = (ApplicatiemeldingType) jaxbUnmarshaller

                    .unmarshal(file);

            System.err.println(Applicatiemelding);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

    public static void main(String[] args) {

        (new ParseApplicatieMelding()).run();

    }

-----------------------------------------------------------------------------

I initially tried this (with an test xml listed below) with a (simple?) coding like an "JAXBContext.newInstance(ApplicatieMeldingType.class) " type of code (in above listing).

However this fails and I think the reason for this is that namespaces are not taken into account (I think it basically says that a namespace was found, but the local (java) object

doesn't know or need one) .

I now try to use a call from the generated ObjectFactory class which has a method that seems to take namespaces into account

( ObjectFactory.createApplicatiemelding());)

However assuming this is the correct approach I have no idea how to construct the parameter that it needs. 

Can someone point out the right value/approach for this ?

For completeness I have included below the ObjectFactorycode and the test xml I try to unmarshall with my program

============================================

//

// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.2.4-2

// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>

// Any modifications to this file will be lost upon recompilation of the source schema.

// Generated on: 2015.12.01 at 12:26:38 PM CET

//

package nl.prorail.prorail.applicatiemelding;

import javax.xml.bind.JAXBElement;

import javax.xml.bind.annotation.XmlElementDecl;

import javax.xml.bind.annotation.XmlRegistry;

import javax.xml.namespace.QName;

/**

* This object contains factory methods for each

* Java content interface and Java element interface

* generated in the nl.prorail.prorail.applicatiemelding package.

* <p>An ObjectFactory allows you to programatically

* construct new instances of the Java representation

* for XML content. The Java representation of XML

* content can consist of schema derived interfaces

* and classes representing the binding of schema

* type definitions, element declarations and model

* groups.  Factory methods for each of these are

* provided in this class.

*

*/

@XmlRegistry

public class ObjectFactory {

    private final static QName _Applicatiemelding_QNAME = new QName("http://www.prorail.nl/Prorail/ApplicatieMelding", "Applicatiemelding");

    /**

     * Create a new ObjectFactory that can be used to create new instances of schema derived classes for package: nl.prorail.prorail.applicatiemelding

     *

     */

    public ObjectFactory() {

    }

    /**

     * Create an instance of {@link ApplicatiemeldingType }

     *

     */

    public ApplicatiemeldingType createApplicatiemeldingType() {

        return new ApplicatiemeldingType();

    }

    /**

     * Create an instance of {@link JAXBElement }{@code <}{@link ApplicatiemeldingType }{@code >}}

     *

     */

    @XmlElementDecl(namespace = "http://www.prorail.nl/Prorail/ApplicatieMelding", name = "Applicatiemelding")

    public JAXBElement<ApplicatiemeldingType> createApplicatiemelding(ApplicatiemeldingType value) {

        return new JAXBElement<ApplicatiemeldingType>(_Applicatiemelding_QNAME, ApplicatiemeldingType.class, null, value);

    }

}

===============================================

test xml

================================================

<?xml version="1.0" encoding="UTF-8"?>

<ns1:Applicatiemelding xmlns:ns1="http://www.prorail.nl/Prorail/ApplicatieMelding"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.prorail.nl/Prorail/ApplicatieMelding file:/C:/data/GEN_SE_BNS/bw/GEN_SE_BNS/SharedResources/Schemas/ApplicatieMelding.xsd">

    <SysteemId>SysteemId0</SysteemId>

    <Timestamp>2006-05-04T18:13:51.0Z</Timestamp>

    <ApplicatieInstantie>Applicat</ApplicatieInstantie>

    <ApplicatieVerkorting>ApplicatieVerkorting0</ApplicatieVerkorting>

    <ProcesId>ProcesId</ProcesId>

    <FunctieId>FunctieI</FunctieId>

    <SeverityCode>INFO</SeverityCode>

    <MeldingNummer>1234567890123456789</MeldingNummer>

    <MeldingTekst>MeldingTekst0</MeldingTekst>

    <Component>Component0</Component>

    <ComponentToestand>0</ComponentToestand>

</ns1:Applicatiemelding>

================================================

Answers

  • GeertsP-JavaNet
    GeertsP-JavaNet Member Posts: 14
    edited Dec 1, 2015 3:54PM

    Hi All,

    after some further experimentation I came up with the following (educated guess) code

    (some statements commented out !)

    =========================================================

    try {

                File file = new File("c:/data/ApplicatieMelding.xml");

                ApplicatiemeldingType Applicatiemelding = new ObjectFactory()

                        .createApplicatiemeldingType();

                JAXBContext jaxbContext = JAXBContext

                        .newInstance("nl.prorail.prorail.applicatiemelding");

                // JAXBContext jaxbContext = JAXBContext.newInstance(new

                // ObjectFactory().createApplicatiemelding(Applicatiemelding));

                // JAXBElement<ApplicatiemeldingType> amT = new

                // ObjectFactory().createApplicatiemelding(Applicatiemelding);

                Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

                Object result = jaxbUnmarshaller.unmarshal(file);

                System.err.println(result.getClass());

            } catch (Exception e) {

                e.printStackTrace();

            }

    ============================================================

    When I run this it doesn't fall over (which is something) but the problem is that I don't know what I have got

    It says that the object type is javax.xml.bind.JAXBElement but I don't know how to handle this further (casting to ApplicatiemeldingType is not possible)

    Peter

This discussion has been closed.