1

もう 1 つ難しい質問があります。

E.g. Person Class has: --String firstName --String lastName --Map stringMap

   Person person = new Person ();
   person.setFirstName("FirstName");
   person.setLastName("LastName");
   Map<String,String> stringMap = new HashMap<String,String>();
   stringMap.put("IwantThisKeyInXml","IwantThisValueInXml");
   stringMap.put("IDONTwantThisKeyInXml","IDONTwantThisValueInXml");


   InputStream iStream1 = classLoader.getResourceAsStream("person-binding.xml");
   List<Object> fileList = new ArrayList<Object>();
            fileList.add(iStream1);
   Map<String, Object> properties = new HashMap<String,Object>();               

   properties.put(JAXBContextProperties.OXM_METADATA_SOURCE,  fileList);
   JAXBContext ctx = JAXBContext.newInstance(new Class[] { GaDictionary.class, Person.class }, properties);

   Marshaller marshaller = ctx.createMarshaller();
   marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

   Writer output = new StringWriter();
   marshaller.marshal(person, output);
   System.out.println(output);

person-binding.xml は以下です

   <?xml version="1.0"?>
   <xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="my.test.model"  xml-mapping-metadata-complete="true">
    <xml-schema
        element-form-default="QUALIFIED"/>
    <java-types>
        <java-type name="Person"  xml-accessor-type="NONE">
            <xml-root-element/>
            <xml-type prop-order="firstName lastName"/>
            <java-attributes>
                <xml-element java-attribute="firstName" name="first-name"/>
                <xml-element java-attribute="lastName" name="last-name"/>
                <xml-element java-attribute="stringMap" name="string-map"/>
            </java-attributes>
        </java-type>
      </java-types>
    </xml-bindings>

したがって、結果の定義は次のとおりです。

   <?xml version="1.0" encoding="UTF-8"?>
   <person>
   <first-name>FirstName</first-name>
   <last-name>LastName</last-name>
   <string-map>
      <entry>
         <key>IwantThisKeyInXml</key>
         <value>IwantThisKeyInXml</value>
      </entry>
      <entry>
         <key>IDONTwantThisKeyInXml</key>
         <value>IDONTwantThisKeyInXml</value>
      </entry>
   </string-map>
   </person>

stringMap でそのエントリを除外するにはどうすればよいですか? 仮想アクセス方式でやってみたけどうまく設定できなかったかも?!マーシャリング後にその値を削除する必要がありますか? スマートで保守可能な方法はどれですか?

最後の質問は、プロパティに null 値があるかどうかです。person-binding-xml ファイル (oxm.file) を構成して相対 xml タグを空にするにはどうすればよいですか?

モデル クラスを変更することもできますが、可能であれば、コード行を追加しないことをお勧めします。(これが、xml ファイルに入力した理由です)

したがって、私が取得したい結果は次のとおりです。

 <?xml version="1.0" encoding="UTF-8"?>
   <person>
     <first-name>FirstName</first-name>
     <last-name>LastName</last-name>
     <string-map>
       <entry>
         <key>IwantThisKeyInXml</key>
         <value>IwantThisKeyInXml</value>
       </entry>
      </string-map>
  </person>

関連する 2 番目の質問: nillable="true" を試してみましたが、うまくいきません。したがって、たとえば、stringMap または firstName などに null 値がある場合、それぞれ取得し、本文でタグを閉じます。

または、私が取得したい別の方法は次のとおりです。

 <?xml version="1.0" encoding="UTF-8"?>
   <person>
     <first-name>FirstName</first-name>
     <last-name>LastName</last-name>
     <string-map>
       <entry>
         <key>IwantThisKeyInXml</key>
         <value>IwantThisKeyInXml</value>
       </entry>
       <entry><!-- I have the entry but I have an empty value-->
         <key>KEY</key>
         <value></value>
       </entry>
      </string-map>
  </person>

ありがとうございます

4

3 に答える 3

4

あなたのソリューションでは、null-policy は正しい考えですが、マップ全体ではなく StringEntryType の値属性にある必要があります。したがって、バインディング ファイルには次のようなものが含まれている必要があります。

 <java-type name="StringEntryType">
        <java-attributes>
            <xml-element java-attribute="value" name="value">
                <xml-null-policy null-representation-for-xml="EMPTY_NODE"/>
            </xml-element>
        </java-attributes>
    </java-type>

あなたのソリューションは良さそうに見えますが、MOXy の読み取り専用および書き込み専用の属性を使用する別のソリューションも投稿すると思います。この例では、アンマーシャル中に変数 myMap が設定されますが、マーシャル中に getModifiedMap メソッドから返された Map が呼び出されます。getModifiedMap では、null 値も空の文字列に置き換えて、空のタグがマーシャリングされるようにします。

public class Root {

    public Map<String, String> myMap = new HashMap<String, String>();

    public Map<String, String> getModifiedMap(){
         Map modifiedMap = new HashMap<String, String>();       
         Set<Entry<String, String>> entries = myMap.entrySet();
         Iterator<Entry<String, String>> iter = entries.iterator();
         while(iter.hasNext()){
             Entry<String, String> nextEntry = iter.next();
             String nextKey = nextEntry.getKey();
             if(!nextKey.equals("omitthiskey")){
                 String nextValue = nextEntry.getValue();
                 if(nextValue == null){
                     nextValue ="";
                 }               
                 modifiedMap.put(nextKey, nextValue);
             }
         }
         return modifiedMap;
    }

    public void setModifiedMap(Map<String, String> newMap){
        //this method shouldn't get hit but needs to be present 
    }
}

対応するバインディング ファイルには、次のような内容が含まれます。

<xml-bindings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm" package-name="test2" >
    <xml-schema element-form-default="QUALIFIED"/>  
    <java-types>
    <java-type name="Root"  xml-accessor-type="NONE">
        <xml-root-element/>
        <java-attributes>
            <xml-element java-attribute="myMap" name="myMap" read-only="true" />
            <xml-element java-attribute="modifiedMap" name="myMap" write-only="true"/>                      
        </java-attributes>
    </java-type>                    
    </java-types>
</xml-bindings>
于 2013-04-17T18:10:25.077 に答える
1

特定の Map エントリが XML にマーシャリングされないようにしたい場合は、マーシャリング時に不要なエントリを削除する XmlAdapter を提供できます。

import java.util.Map;

import javax.xml.bind.annotation.adapters.XmlAdapter;

public final class MyAdapter extends XmlAdapter<Map<String, String>, Map<String, String>> {

    private final String OMIT = "IDONTwantThisKeyInXml";

    @Override
    public Map<String, String> unmarshal(Map<String, String> arg0) throws Exception {
        return arg0;
    }

    @Override
    public Map<String, String> marshal(Map<String, String> arg0) throws Exception {
        if (arg0 != null) {
            arg0.remove(OMIT);
        }
        return arg0;
    }

}

2 番目の質問がよくわかりません。どのような動作が必要かについて、もう少し説明していただけますか?

お役に立てれば、

リック

于 2013-04-11T19:27:11.640 に答える
0

私は正しい解決策を見つけました:

        import java.util.HashMap;
        import java.util.Map;
        import java.util.Map.Entry;

        import javax.xml.bind.annotation.adapters.XmlAdapter;

        public final class StringMapAdapter extends XmlAdapter<StringAdapterMap, Map<String, String>> {

            private final String OMIT = "birthPlaceString";

            @Override
            public Map<String, String> unmarshal(StringAdapterMap v) throws Exception {
                 HashMap<String, String> hashMap = new HashMap<String, String>();
                 System.out.println("unmarshal"); 
                 for(StringEntryType myEntryType : v.entry) {
                     hashMap.put(myEntryType.key, myEntryType.value);
                  }
                  return hashMap;
            }

            @Override
            public StringAdapterMap marshal(Map<String, String> v) throws Exception {
                StringAdapterMap myMapType = new StringAdapterMap();
              for(Entry<String, String> entry : v.entrySet()) {
                  StringEntryType EntryType = new StringEntryType();
                   EntryType.key= entry.getKey();
                   EntryType.value = entry.getValue();
                   if (!OMIT.equals(EntryType.key))
                       myMapType.entry.add(EntryType);
              }
              return myMapType;

            }

StringAdapterMap クラス:

        import java.util.ArrayList;
        import java.util.List;

        public class StringAdapterMap {
             public List<StringEntryType> entry = new ArrayList<StringEntryType>();

        }

StringEntryType クラス:

        public class StringEntryType {

               public String key;

               public String value;

        }

oxm.file でアダプターを構成することを忘れないでください

     <xml-element java-attribute="stringMap" name="string-map" >
      <xml-java-type-adapter value="it.cineca.jaxb.adapter.StringMapAdapter" />    
     </xml-element>
于 2013-04-17T14:47:59.427 に答える