Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jaxb unmarshalls fixml object but all fields are null

I have a small XML document in the FIXML format. I'm unmarshalling them using jaxb.

The problem

The process complete without errors but the objects which are created are completely null. Every field is empty. The fields which are lists (like the Qty) have the right number of object in them. But the fields of those objects are also null.

Setup

I've downloaded the FIXML schema from here and I've created the classes with xjc and the maven plugin. They are all in the package org.fixprotocol.fixml_5_0_sp2. I've got the sample xml in a file

FIXML.XML

<?xml version="1.0" encoding="ISO-8859-1"?>
<FIXML>
<Batch>
    <PosRpt>
    <Pty ID="GS" R="22"/>
    <Pty ID="01" R="5"/>
    <Pty ID="6U8" R="28">
        <Sub ID="2" Typ="21"/>
    </Pty>
    <Pty ID="GS" R="22"/>
    <Pty ID="6U2" R="2"/>
    <Instrmt ID="GHPKRW" SecTyp="FWD" MMY="20121018" MatDt="2012-10-18" Mult="1" Exch="GS" PxQteCcy="KJS" FnlSettlCcy="GBP" Fctr="0.192233298" SettlMeth="G" ValMeth="FWDC2" UOM="Ccy" UOMCCy="USD">
        <Evnt EventTyp="121" Dt="2013-10-17"/>
        <Evnt EventTyp="13" Dt="2013-10-17"/>
    </Instrmt>
    <Qty Long="0.000" Short="22000000.000" Typ="PNTN"/>
    <Qty Long="0.000" Short="22000000.000" Typ="FIN"/>
    <Qty Typ="DLV" Long="0.00" Short="0.00" Net="0.0"/>
    <Amt Typ="FMTM" Amt="32.332" Ccy="USD"/>
    <Amt Typ="CASH" Amt="1" Rsn="3" Ccy="USD"/>
    <Amt Typ="IMTM" Amt="329.19" Ccy="USD"/>
    <Amt Typ="DLV" Amt="0.00" Ccy="USD"/>
    <Amt Typ="BANK" Amt="432.23" Ccy="USD"/>
</PosRpt>

Then I'm calling the unmarshaller with custom event handler which just throws an exception on a parse error. The parsing complete so I know there are no errors being generated. I'm also handling the namespace as suggested here

// sort out the file
String xmlFile = "C:\\FIXML.XML.xml";
System.out.println("Loading XML File..." + xmlFile);
InputStream input = new FileInputStream(xmlFile);
InputSource is = new InputSource(input);

// create jaxb context
JAXBContext jc = JAXBContext.newInstance("org.fixprotocol.fixml_5_0_sp2");
Unmarshaller unmarshaller = jc.createUnmarshaller();

// add event handler so jacB will fail on an error
CustomEventHandler validationEventHandler = new CustomEventHandler();
unmarshaller.setEventHandler(validationEventHandler);

// set the namespace
NamespaceFilter inFilter = new NamespaceFilter("http://www.fixprotocol.org/FIXML-5-0-SP2", true);

inFilter.setParent(SAXParserFactory.newInstance().newSAXParser().getXMLReader());
SAXSource source = new SAXSource(inFilter, is);

// GO!
JAXBElement<FIXML> fixml = unmarshaller.unmarshal(source, FIXML.class);

The fixml object is created. In the above sample the Amt array will have five element which matches the number of amts in the file. But all the fields like ccy are null. I've put breakpoints in the classes created by xjc and none of the setters are ever called.

So it appears that jaxb is unmarshalling and creating all the correct objects, but it's never calling the setters??

I'm completely stumped on this. I've seen a few posts that suggrest making sure the package.info file that was generated by xjc is in the packags and I've made sure that it's there. There are no warnings in the IDE about the generated code.

Any help much appreciated.

Update I've tried to set the schema file on the unmarshaller before commencing the unmarshalling.

Schema schema = sf.newSchema(f);
unmarshaller.setSchema(schema);

I wasn't sure which schema to use so I did it in a loop trying each file in turn. The upshot is none of them make it work. They cause the error Invalid content was found starting with element 'PosRpt'.

Which is surprising. I'm now thinking the problem is something to do with namespaces.

Update 2 Still no progress. I have tried JAXB 2.0 & 2.2. Now looking at different maven plugin to call xjc. But I don't think that's it.

Update 3 So now having read the fixml in I'm marshalling it back into a separate file.

// GO!
JAXBElement<FIXML> fixml = unmarshaller.unmarshal(source, FIXML.class);

//Write     
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(fixml, output);

The results are:

inputfile.xml

<FIXML>
    <Batch>
    <PosRpt RptID="5952323" ReqID="434242" SetSesID="EOD" MtchStat="2" PriSetPx="11.284328" SetPx="11.4432" SetPxTyp="1" SettlCcy="EUR" ReqTyp="1" MsgEvtSrc="REG" BizDt="2012-11-17" SettlDt="2018-11-20">
        <Pty ID="CC" R="22"/>
            ....

output.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2">
        <Batch>
            <PosRpt>
                <Pty/>
                <Pty/>
                <Pty/>

So the structure of the file is correct, but it's empty as expected. There is an explicit namespace so I've tried adding that namespace to the test input file but that does not make any difference. Next I'll try populating the fixml object before marshaling it.

Update 4

Not I'm creating a simple FIXML class and marhelling it.

simple_fxixml_out.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2" cv="DDDD">
    <Batch ID="dfddd">
        <PositionReportMessageT Ccy="CCC"/>
    </Batch>
</FIXML>

When I try and read that back in I get:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2">
    <Batch/>

The things I note form this are:

  1. The generated namespace is the same
  2. I've created PositionReportMessageT rather than a PosRpt tag
  3. Even the DDDD attribute on the FIXML does survive the transition.
like image 415
DUFF Avatar asked Nov 04 '22 12:11

DUFF


1 Answers

I think you need to do

saxParserFactory.setNamespaceAware(true)

(I don't think you need the namespaceFilter)

The javax.xml.bind.JAXB class contains convenience methods which are very useful when trying out marshalling / unmarshalling, by the way.

like image 114
artbristol Avatar answered Nov 09 '22 11:11

artbristol