Jaxb unmarshalls fixml对象,但所有字段都为null

DUF*_*UFF 5 java xml jaxb xml-parsing

我有一个FIXML格式的小型XML文档.我正在使用jaxb解组它们.

问题

该过程完成但没有错误,但创建的对象完全为空.每个字段都是空的.作为列表的字段(如数量)在其中具有正确数量的对象.但是这些对象的字段也是null.

建立

我从这里下载了FIXML模式 ,我用xjc和maven插件创建了类.它们都在org.fixprotocol.fixml_5_0_sp2包中.我在文件中有样本xml

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>
Run Code Online (Sandbox Code Playgroud)

然后我用自定义事件处理程序调用unmarshaller,它只会在解析错误上抛出异常.解析完成,所以我知道没有生成错误.我也在这里处理命名空间

// 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);
Run Code Online (Sandbox Code Playgroud)

fixml对象已创建.在上面的示例中,Amt数组将有五个元素与文件中的amts数相匹配.但像ccy这样的所有领域都是空的.我在xjc创建的类中放置了断点,并且没有调用任何setter.

所以似乎jaxb是解组并创建所有正确的对象,但它永远不会调用setter?

我完全被这个难过了.我看过几篇帖子,确保xjc生成的package.info文件在包装中,我确保它就在那里.IDE中没有关于生成的代码的警告.

任何帮助非常感谢.

更新 我尝试在开始解组之前在unmarshaller上设置模式文件.

Schema schema = sf.newSchema(f);
unmarshaller.setSchema(schema);
Run Code Online (Sandbox Code Playgroud)

我不确定使用哪种模式,所以我在循环中依次尝试每个文件.结果是它们都没有成功.它们导致错误从元素'PosRpt'开始发现无效内容.

这是令人惊讶的.现在我想的问题是什么做的命名空间.

更新2 仍然没有进展.我试过JAXB 2.0和2.2.现在看着不同的maven插件来调用xjc.但我不认为就是这样.

更新3 现在我已经阅读了fixml,我将它编组回一个单独的文件中.

// 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);
Run Code Online (Sandbox Code Playgroud)

结果是:

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"/>
            ....
Run Code Online (Sandbox Code Playgroud)

与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/>
Run Code Online (Sandbox Code Playgroud)

所以文件的结构是正确的,但是它是空的,如预期的那样.有一个显式的命名空间,所以我尝试将该命名空间添加到测试输入文件,但这没有任何区别.接下来,我将尝试在编组之前填充fixml对象.

更新4

不是我正在创建一个简单的FIXML类并将其混淆.

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>
Run Code Online (Sandbox Code Playgroud)

当我尝试阅读时,我得到:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2">
    <Batch/>
Run Code Online (Sandbox Code Playgroud)

我注意到的事情是:

  1. 生成的命名空间是相同的
  2. 我创建了PositionReportMessageT而不是PosRpt标记
  3. 甚至FIXML上的DDDD属性也能在转换过程中存活下来.

art*_*tol 2

我认为你需要做

saxParserFactory.setNamespaceAware(true)

(我认为你不需要命名空间过滤器)

顺便说一句,该类javax.xml.bind.JAXB包含一些方便的方法,这些方法在尝试编组/解组时非常有用。