5

JAXB を使用して作成されたデータモデルを使用して、そこから XML を直接生成できます

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>\
<metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0">
<artist-list offset="0" count="1">
   <artist ext:score="100" type="Group" id="4302e264-1cf0-4d1f-aca7-2a6f89e34b36">       
       <name>Farming Incident</name>
       <ipi-list>
          <ipi>1001</ipi>
       </ipi-list>
   </artist>
</artist-list>
</metadata>

また、Jersey の助けを借りて、Natural 表記法を使用して JSON も生成します

"artist-list":
    {"offset":0,
     "count":1,
     "artist":[
         {"score":"100",
          "type":"Group",
          "id":"4302e264-1cf0-4d1faca7-2a6f89e34b36",
          "name":"Farming Incident",
          "ipi-list":
              {
                  "ipi":[
                       "1001"
                    ]
             }
          }]
     }

Xml は問題ありません。json はほぼ問題ありませんが、Json は ipi-list や artist-list などの要素を持つ配列を直接サポートしているため、非常に json とは思えません。私のモデルから json のような json をさらに生成することは可能ですか?

要求された追加情報 json は 、JAXB と Jersey を使用して、この MMD スキーマhttp://svn.musicbrainz.org/mmd-schema/trunk/brainz-mmd2-jaxb/src/main/resources/musicbrainz_mmd-2.0.xsdから生成されます。 http://svn.musicbrainz.org/search_server/trunk/servlet/src/main/java/org/musicbrainz/search/servlet/mmd2/ResultsWriter.javaおよび http://svn.musicbrainz.org/search_server/trunkを参照 してください/servlet/src/main/java/org/musicbrainz/search/servlet/mmd2/ArtistWriter.java

要点は、最小限の手間で1つのスキーマからJsonとXMLを生成できるようにしたいということですが、明らかにJsonが正しく見えないので、改善する方法を探しています(実際には経験がありません)自分自身のjson)

4

5 に答える 5

3

注: 私はEclipseLink JAXB (MOXy)のリーダーであり、JAXB (JSR-222)エキスパート グループのメンバーです。

ユース ケースをサポートするために、EclipseLink JAXB (MOXy) の JSON バインディングと外部マッピング ドキュメントを活用できます。

外部マッピング ファイル (oxml.xml)

@XmlPath(".")MOXyの拡張機能を使用して、オブジェクト モデルの一部を平坦化できます。のパスを指定して、"."MOXy に参照先のオブジェクトを親ノードに含めるように指示します。

<?xml version="1.0"?>
<xml-bindings
    xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
    package-name="forum10699038">
    <java-types>
        <java-type name="Metadata">
            <java-attributes>
                <xml-element java-attribute="artistList" xml-path="."/>
            </java-attributes>
        </java-type>
        <java-type name="Artist">
            <java-attributes>
                <xml-element java-attribute="ipiList" xml-path="."/>
            </java-attributes>
        </java-type>
    </java-types>
</xml-bindings>

jaxb.properties

MOXy を JAXB プロバイダーとして指定するにjaxb.propertiesは、次のエントリを使用して、ドメイン モデルと同じパッケージで呼び出されるファイルを追加する必要があります。

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory

デモ

以下のコードは、XML ドキュメントからオブジェクト モデルを設定し、JSON にマーシャリングします。外部マッピング ファイルを活用し、MOXy を JSON モードにする方法を示します。

package forum10699038;

import java.io.File;
import java.util.*;
import javax.xml.bind.*;

import org.eclipse.persistence.jaxb.JAXBContextProperties;

public class Demo {

    public static void main(String[] args) throws Exception {
        // READ FROM XML
        JAXBContext jcXML = JAXBContext.newInstance(Metadata.class);

        File xml = new File("src/forum10699038/input.xml");
        Unmarshaller unmarshaller = jcXML.createUnmarshaller();
        Metadata metadata = (Metadata) unmarshaller.unmarshal(xml);

        // WRITE TO JSON
        Map<String, Object> properties = new HashMap<String, Object>(3);
        properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, "forum10699038/oxm.xml");
        properties.put(JAXBContextProperties.MEDIA_TYPE, "application/json");
        properties.put(JAXBContextProperties.JSON_INCLUDE_ROOT, false);
        JAXBContext jcJSON = JAXBContext.newInstance(new Class[] {Metadata.class}, properties);

        Marshaller marshaller = jcJSON.createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
        marshaller.marshal(metadata, System.out);
    }

}

出力

{
   "artist" : [ {
      "id" : "4302e264-1cf0-4d1f-aca7-2a6f89e34b36",
      "type" : "Group",
      "score" : "100",
      "name" : "Farming Incident",
      "ipi" : [ "1001" ]
   } ]
}

モクシーとジャージー

Jersey などの JAXB-RS 環境で MOXy を JSON プロバイダーとして簡単に使用できます。


その他のファイル

以下は、すべてが適切に機能することを確認するために作成したバージョンのファイルです。

入力.xml

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<metadata xmlns="http://musicbrainz.org/ns/mmd-2.0#" xmlns:ext="http://musicbrainz.org/ns/ext#-2.0">
    <artist-list offset="0" count="1">
        <artist ext:score="100" type="Group"
            id="4302e264-1cf0-4d1f-aca7-2a6f89e34b36">
            <name>Farming Incident</name>
            <ipi-list>
                <ipi>1001</ipi>
            </ipi-list>
        </artist>
    </artist-list>
</metadata>

メタデータ

package forum10699038;

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Metadata {

    @XmlElement(name="artist-list")
    ArtistList artistList;

}

アーティスト一覧

package forum10699038;

import java.util.List;

public class ArtistList {

    private List<Artist> artist;

}

アーティスト

package forum10699038;

import javax.xml.bind.annotation.*;

@XmlType(propOrder={"name", "ipiList"})
public class Artist {

    @XmlAttribute
    private String id;

    @XmlAttribute
    private String type;

    @XmlAttribute(namespace="http://musicbrainz.org/ns/ext#-2.0")
    private String score;

    @XmlElement(name="ipi-list")
    private IPIList ipiList;

    private String name;

}

IPリスト

package forum10699038;

import java.util.List;

public class IPIList {

    private List<String> ipi;

}

パッケージ情報

@XmlSchema( 
    namespace = "http://musicbrainz.org/ns/mmd-2.0#", 
    elementFormDefault = XmlNsForm.QUALIFIED,
    xmlns={
        @XmlNs(prefix="", namespaceURI = "http://musicbrainz.org/ns/mmd-2.0#")
    }
) 
@XmlAccessorType(XmlAccessType.FIELD)
package forum10699038;

import javax.xml.bind.annotation.*;
于 2012-06-13T09:47:38.570 に答える
1

個人的には注釈はあまり好きではありません。プレーンコードでJSON/XMLを生成する習慣があります。:)

たとえば、Jackson(Gsonも同様)の場合:

mapper = new ObjectMapper();
JsonNode root = mapper.createObjectNode();

JsonNode artist = mapper.createObjectNode();
artist.put("score", "100");
root.put("artist-list", artist);

ArrayNode ipiList = mapper.createArrayNode();
ipi.add("1001");
artist.put("ipi-list", ipiList);

表面的には多くの作業に見えるかもしれません。しかし、私にとって、これはJSONをオブジェクトにマッピングする非常に明確な方法です。基本的に、エンティティクラスにtoJson()メソッドを含めるのが、私の通常の方法です。次に例を示します:https ://github.com/richardzcode/metrics/blob/master/src/main/java/com/rz/metrics/core/entities

でもそれは私だけです。

JAXBの場合、以下のようにエンティティに注釈を付ける必要があると思います。

@XmlElement(name = "ipi-list")
private List<Ipi> ipi;
于 2012-06-11T21:50:50.710 に答える
1

Jersey によって作成される JSON は、サイトで提供されるそのモデルの正確な JSOON 表現です。ここで直面している問題は、フレームワークが正しく機能していないということではなく、サイトがぎこちないデータ モデルを提供していることです。

このサービスがアーティストのリストではなく、アーティスト リスト タイプのオブジェクトを返すのはなぜですか? サービスに ipi-list オブジェクトもあるのはなぜですか? あなたが問うべき本当の質問は、これをどのようにモデル化して、すべてのテクノロジーでより適切に機能させるかということです。

于 2012-06-09T20:15:48.600 に答える
1

ipiList で発生している問題は、Jersey が JSON へのマッピングに使用する基盤となるライブラリの単一要素配列/リストの問題によるものだと思います。

次のブログ投稿 (私のものではありません) は、Jersey を構成する 1 つの方法を示しており、コメントは、JSON 表現を配列に対して正しくするための別の (おそらくもっと単純な) 方法にリンクしています。

http://tugdualgrall.blogspot.co.uk/2011/09/jax-rs-jersey-and-single-element-arrays.html

于 2012-06-11T22:10:37.077 に答える
0

Jersey jsonライブラリのJSON配列とプリミティブフィールドの「バグ」をなんとか解決しました。秘密の要素は、前述の JSONConfiguration と ContextResolver マジックです。私の次の投稿を参照してください。完全なコード例があり、カスタマイズされた ContextResolver と残りの Application クラスは、一見するとややファジーなロジックである可能性があります。

Jersey RESTを使用してJavaプリミティブをシリアライズする方法

  • ゼロ要素または単一要素の Java リストの json 配列
  • 引用符なしのプリミティブ整数またはブール フィールド
于 2012-09-27T16:14:54.550 に答える