3

次のXML/JSON ドキュメントを同等のJAXB/Moxy 注釈付きクラスに正しくマップする方法を見つけようとしています。私の例では人を説明するドキュメントのモデル要素はフリーフォームで あることに注意してください。つまり、静的に認識されていない任意の種類の XML 要素/JSON オブジェクトである可能性があります。

XML ドキュメント:

<form>
   <title>Person Form</title>
   <model>
      <person>
         <name>John</name>
         <surname>Smith</surname>
         <address>
           <street>Main St.</street>
           <city>NY</city>
           <country>USA</country>
         </address>
     <person>
   </model>
</form>

同等の JSON ドキュメント:

{  
   "title":"Form Title",  
   "model":{  
      "person":{  
         "name":"John",  
         "surname":"Smith",  
         "address":{  
            "street":"Main St.",  
            "city":"NY",  
            "country":"USA"  
         }          
      }  
   }
}

モデルフィールドをMapとしてマップすると考えました。値はプリミティブ型またはMap 自体である可能性があります。このマッピングは、私のニーズに対して十分に表現力があります。

@XmlReadTransformer、@XmlWriteTransformer MOXY アノテーションを試してみましたが、成功しませんでした (buildAttributeValue で取得したレコード パラメーターは常に null です)。

@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) 
public class Form {
   private String title; 
   private Model model;
   ....getters and setters....
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Model {

    @XmlElement
    @XmlReadTransformer(transformerClass = Transformer.class)
    @XmlWriteTransformers({ @XmlWriteTransformer(xmlPath = "./*", transformerClass = Transformer.class) })
    private Map<String, Object> data;

    public Map<String, Object> getData() {
        return data;
    }

    public void setData(Map<String, Object> data) {
        this.data = data;
    }

    public static class Transformer implements AttributeTransformer, FieldTransformer {

        private AbstractTransformationMapping tm;

        public Transformer() {
        }

        @Override
        public void initialize(AbstractTransformationMapping tm) {
            this.tm = tm;
        }

        @Override
        public Map<String, Object> buildAttributeValue(Record r, Object o,
                Session s) {
            Map<String, Object> data = new HashMap<String, Object>();
            // TODO: ????
            return data;
        }

        @Override
        public Object buildFieldValue(Object arg0, String arg1, Session arg2) {
// TODO
            return null;
        }

    }
}

この問題を解決する適切な方法、または「モデル」フィールドをモデル化する別の方法を提案できますか?

4

3 に答える 3

2

モデルがデータを org.w3c.dom.Node として保持する場合、うまくいきますか?

 @XmlAnyElement
 public Node data;

その後、MOXy はこのシナリオを処理しますが、フォーマットされた XML を読み込んでから JSON に書き戻す場合 (出力の値として余分な改行/空白)、バグがあると思います。ただし、このセットアップでは、提供された XML を読み書きし、提供された JSON を読み書きすることができました。

ソリューションで注意すべき点が 1 つあります。現在、JSON アンマーシャリングがイベントを報告する方法では、属性と要素を区別しようとします。例で JSON を読み書きすると、キーと値のペアが重複していることに気付くでしょう。この問題のバグ ( https://bugs.eclipse.org/bugs/show_bug.cgi?id=407452 ) をオープンしましたが、アンマーシャラーで UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX プロパティを設定する回避策があります。

その JSON_ATTRIBUTE_PREFIX が設定されていない場合、各キーを要素と属性として報告し、一致するかどうかを確認しますが、JSON_ATTRIBUTE_PREFIX を設定すると、そのプレフィックスで始まるもののみが属性として扱われるため、JSON_ATTRIBUTE_PREFIX を次のように設定できます。キー名が通常始まらないもの:

   unmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, "@");  

または明確にする

   unmarshaller.setProperty(UnmarshallerProperties.JSON_ATTRIBUTE_PREFIX, "THIS_STRING_WILL_NEVER_BE_USED_AS_THE_START_OF_A_KEY_NAME");

この例では、JSON にルートがないため、JSON_INCLUDE_ROOT プロパティを false に設定する必要もあります。つまり、JSON に「フォーム」キーをラップしていません。

   u.setProperty(UnmarshallerProperties.JSON_INCLUDE_ROOT,false);
于 2013-05-07T18:23:07.657 に答える
2

Person (またはあなたが持っている他のクラス) は、実行時に利用できるクラスですか? XML/JSON を少し変更して、対応するクラスを示す type 属性を含めることはできますか? もしそうなら、ここの例があなたを助けるかもしれません http://blog.bdoughan.com/2012/02/xmlanyelement-and-xmladapter.html

あなたのモデルはこのようなものになります

@XmlAnyElement
private List<Parameter> data;

リンクされた例で ParameterAdapter を使用すると、XML および JSON で使用している type 属性を含める必要があります。

{
   "title" : "Form Title",
   "model" : {
      "person" : {
         "type" : "test.Person",
         "name" : "John",
         "surname" : "Smith",
...
}

また

<form>
   <title>Person Form</title>
   <model>
      <person type="test.Person">
         <name>John</name>
         <surname>Smith</surname>
...
</form>
于 2013-05-02T20:02:11.220 に答える