2012-10-28 8 views
5

私はFIXML形式の小さなXMLドキュメントを持っています。私はjaxbを使用してそれらをアンマーシャリングしています。Jaxbはfixmlオブジェクトをアンマーシャリングしますが、すべてのフィールドはnullです

エラーなしで完全なプロセスの問題が、作成されたオブジェクトは、完全にはnullです。 すべてのフィールドは空です。リスト(Qtyのような)であるフィールドは、その中に正しい数のオブジェクトを持っています。しかし、これらのオブジェクトのフィールドもnullです。

セットアップ

私はhere からFIXMLスキーマをダウンロードしたと私はXJCとMavenプラグインでクラスを作成しました。それらはすべてorg.fixprotocol.fixml_5_0_sp2パッケージに入っています。 私はその後、私はちょうど上の例外をスローするカスタムイベントハンドラとアンマーシャラーを呼んでいるファイルに

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> 

をサンプルXMLを持っていますパースエラー。 解析が完了したので、エラーは生成されません。 FIXMLオブジェクトが作成され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); 

提案されているよう 私はまた、名前空間を処理しています。上記のサンプルでは、​​Amt配列には、ファイル内のamtsの数に一致する5つの要素があります。 しかし、ccyのようなすべてのフィールドはnullです。私はxjcによって作成されたクラスにブレークポイントを入れましたが、セッターのどれも呼ばれることはありません。

したがって、jaxbはアンマーシャルしてすべての正しいオブジェクトを作成しているようですが、決してセッターを呼び出すことはありませんか?

私はこれを完全に困惑しています。 xjcによって生成されたpackage.infoファイルがパッケージに入っていることを確認し、それがそこにあることを確認したことを確認した記事をいくつか見てきました。 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); 

結果は以下のとおりです。

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/> 

ので、ファイルの構造は正しいですが、それはです期待どおり空になります。明示的な名前空間があるので、その名前空間をテスト入力ファイルに追加しようとしましたが、違いはありません。次に、マーシャリングする前にfixmlオブジェクトに値を設定します。

更新4

私はシンプルなFIXMLクラスを作成し、それをmarhellingていません。

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/> 

事を、私はこれがあるフォームの点に注意してください。

  1. 生成します名前空間は同じです
  2. 私はPosRptタグではなくPositionReportMessageTを作成しました
  3. FIXMLのDDDD属性でさえも移行が生き残ります。
+1

いくつかのサンプルデータでJAXBオブジェクトを作成してからファイルにマーシャリングしてみてください。読み込んだときにJAXBオブジェクトに戻るかどうかを確認します。生成されたファイルにある名前空間を見てください。 – artbristol

+0

これは良い考えです。それは行く(更新に従う)を与えます。 – DUFF

答えて

2

は私が

javax.xml.bind.JAXBクラスはマーシャリングを試すときに非常に便利です便利なメソッドが含まれています(私はあなたがnamespaceFilter必要はないと思う)あなたは

saxParserFactory.setNamespaceAware(true)

を行う必要があると思います/ unmarshalling、ところで。

+0

ありがとう、あなたにスポットがあります。 – DUFF

0

は、それが簡単に続いて(次は、私自身の概念実証の簡単なコードである)と結合し、トラバースするJAXBを使用 https://javalibs.com/artifact/com.github.xgp/fixml

を(あなたがそれをロードするためにMavenを使用することができます)、次のFIXMLライブラリを使用することが判明します:

JAXBContext jaxbContext = JAXBContext.newInstance(FIXML.class); 
    Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); 

    FIXML fixml = (FIXML) unmarshaller.unmarshal(new StringReader(fixmlOrder)); 

    ExecutionReportMessageT er = (ExecutionReportMessageT) fixml.getMessage().getValue(); 
    if(er.getTrdDt() != null){ 
     System.out.println(er.getTrdDt().toGregorianCalendar().getTime()); 
    } 
    System.out.println(ToStringBuilder.reflectionToString(er,ToStringStyle.MULTI_LINE_STYLE)); 
関連する問題