FIXML 形式の小さな XML ドキュメントがあります。私はjaxbを使用してそれらをアンマーシャリングしています。
問題
プロセスはエラーなしで完了しましたが、作成されたオブジェクトは完全に null です。すべてのフィールドは空です。リストであるフィールド (Qty など) には、適切な数のオブジェクトが含まれています。ただし、これらのオブジェクトのフィールドも 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>
次に、解析エラーで例外をスローするカスタムイベントハンドラーでアンマーシャラーを呼び出しています。解析が完了したので、エラーが生成されていないことがわかりました。ここで提案されているように、名前空間も処理しています
// 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);
fixml オブジェクトが作成されます。上記のサンプルでは、Amt 配列には、ファイル内の amt の数と一致する 5 つの要素があります。ただし、ccy などのすべてのフィールドは null です。xjc によって作成されたクラスにブレークポイントを配置しましたが、どのセッターも呼び出されません。
したがって、jaxb はアンマーシャリングしてすべての正しいオブジェクトを作成しているように見えますが、セッターを呼び出すことはありませんか??
私はこれに完全に困惑しています。xjcによって生成されたpackage.infoファイルがpackagsにあることを確認することを提案する投稿をいくつか見ましたが、そこにあることを確認しました。生成されたコードに関する警告は IDE にありません。
どんな助けでも大歓迎です。
更新 アンマーシャリングを開始する前に、アンマーシャラーにスキーマ ファイルを設定しようとしました。
Schema schema = sf.newSchema(f);
unmarshaller.setSchema(schema);
どのスキーマを使用すればよいかわからなかったので、ループで各ファイルを順番に試しました。結果として、それらのどれもそれを機能させません。それらは、要素 'PosRpt' で始まる無効なコンテンツが見つかりましたというエラーを引き起こします。
これは驚くべきことです。私は今、問題は名前空間に関係していると考えています。
更新 2 まだ進展はありません。JAXB 2.0 & 2.2 を試しました。xjc を呼び出す別の Maven プラグインを検討しています。でもそれだけではないと思います。
更新 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);
結果は次のとおりです。
入力ファイル.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/>
したがって、ファイルの構造は正しいですが、予想どおり空です。明示的な名前空間があるため、その名前空間をテスト入力ファイルに追加しようとしましたが、違いはありません。次に、マーシャリングする前に、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>
それを読み返そうとすると、次のようになります。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<FIXML xmlns="http://www.fixprotocol.org/FIXML-5-0-SP2">
<Batch/>
私がこれからメモしたことは次のとおりです。
- 生成された名前空間は同じです
- PosRpt タグではなく、PositionReportMessageT を作成しました
- FIXML の DDDD 属性でさえ、移行後も存続します。