JSON を XML に変換する Java GsonとJAXBを使用する

⚡ スマートサマリー

JSON を XML に変換する Java GsonとJAXBをmapで使用ping 両方の形式を同じ注釈付きに Java 各クラスについて説明します。この記事では、各フォーマットを定義し、プロジェクトを設定し、JAXBを使用してXMLをアンマーシャリングし、Gsonを使用してJSONを書き込み、その逆のプロセスを実行します。

  • 🗝️ JSON構造: データは、中括弧で囲まれたキーと値のペアとして格納され、各エントリはカンマで区切られます。
  • 🏷️ XML構造: データはネストされたノードに格納され、すべての開始タグには対応する終了タグが必要です。
  • 🔗 共有モデル: 注釈付きの1セット Java クラスは橋渡し役を果たすため、どちらの形式も直接他方の形式に解析されることはありません。
  • 📥 解隊: JAXBはXMLファイルを読み込み、データが入力されたデータを返します。 Java オブジェクトツリーをUnmarshallerクラスを通して処理します。
  • 📤 ストリーミング配信: Gson JsonWriter beginObject、name、value、endObjectの呼び出しによって、JSONを段階的に出力します。
  • 🔄 Reverse パス: JsonReaderはJSONからオブジェクトを再構築し、JAXB MarshallerはそれらをXMLとして書き出します。
  • ⚠️ 実行時の注意: JAXBはJDKを Java 11、したがってjakarta.xml.bindの依存関係を明示的に追加する必要があります。

JSONをXMLに変換する Java

JSONとは何ですか?

JSONは、 JavaJSON(Script Object Notation)は、ほとんどのプログラミング言語が読み取れる規則に従ったデータ形式です。ファイルへの保存やデータベースへの格納も容易です。JSON形式は、キーと値のペアを使用してデータを記述します。

次の例では、個人情報を格納するJSON文字列を定義します。

{
"username" : "guru99user",
"email" : "guru99user@mail.com"
}

JSONの構文は非常にシンプルです。各データ項目はキーと値の2つの部分から構成され、それぞれがレコード内のフィールド名とその値に対応します。さらに詳しく見ていくと、次のようなルールがいくつかあります。

  • JSON 文字列は中括弧 {} で囲まれます。
  • JSONのキーは二重引用符で囲む必要があり、文字列値も同様に引用符で囲む必要があります。
  • データ(キーと値のペア)が複数ある場合は、カンマ(,)で区切ります。
  • JSONキーには、スペースを含まない英字、数字、またはアンダースコア文字を使用し、最初の文字は数字であってはなりません。

XMLとは何ですか?

XMLは、ワールドワイドウェブコンソーシアムによって提案された拡張マークアップ言語の略です(https://www.w3.org/)他のマークアップ言語を作成するために使用します。これは、さまざまな種類のデータを記述できるシンプルなサブセットなので、システム間でデータを共有する際に非常に便利です。

XML のタグは事前定義されていないことがよくありますが、ユーザーの規則に従って作成されます。 XML HTML の利点に基づいた新機能が導入されています。

さまざまなシステムやソリューションに役立つXMLの機能がいくつかあります。

  • XML は拡張可能です: XML を使用すると、アプリケーションに合わせて独自のカスタム タグを作成できます。
  • XMLはデータを伝送するものであり、表示するものではありません。XMLを使用すると、表示方法に関係なくデータを保存できます。
  • XML は共通標準です。XML は World Wide Web Consortium (W3C) によって開発され、オープン標準として利用できます。

XMLはネストされたノード構造に基づいて構築されています。各ノードには、以下のように開始タグと終了タグがあります。

<node>content</node>

その中で:

  • これはオープンタグであり、このタグの名前はあなたが定義します。
  • これは閉じタグであり、このタグの名前は開始タグの名前と一致していなければなりません。
  • コンテンツ このタグの内容です。

各XMLファイルの先頭には、使用中のXMLバージョンを示すタグを宣言する必要があります。指示タグの構文は次のとおりです。

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

JSONとXML:主な違い

どちらの形式も構造化データを扱っており、以下の表はプロジェクトでこれらの形式間でデータを移行する必要がある理由を示しています。

JSONの XML
構文スタイル キーと値のペア ネストされたタグ
データ型 文字列、数値、ブール値、null、配列、オブジェクト テキストのみ、型はスキーマから取得されます
Attributes サポートされていません あらゆる要素でサポートされています
コメント サポートされていません サポート
冗長性 コンパクト タグが繰り返されるため、より冗長になります。
スキーマ検証 JSONスキーマ(オプション) DTDとXSD、成熟
典型的な使用 Web APIと設定 企業向けメッセージングとドキュメント

グソンとは何ですか?

グソン (https://github.com/google/gson)です。 Java ユーザーが変換できるライブラリ Java オブジェクトを JSON 文字列に変換し、また JSON 文字列をオブジェクトに戻す Java オブジェクト。Gsonは任意の Java ソースコードが不明な既存のオブジェクトも含め、オブジェクト全般。

バージョン1.6以降、Gsonは2つのクラスを導入しました。 Jsonリーダー (NAIST) と JsonWriterJSONデータのストリーミング処理を提供する。

  • JsonWriter – ストリーミング書き込みを JSON に行います。 JsonWriter オブジェクト。JSON オブジェクトの作成を開始および完了するには、次の関数を使用します。 beginObject() (NAIST) と endObject()これらの2つの呼び出しの間で、データをペア(キー => 値)として書き込みます。
JsonWriter writer = new JsonWriter();
writer.beginObject();
writer.name("key").value("value");
writer.endObject();
  • Jsonリーダー – JSONからのストリーミング読み込み。まず、JsonReaderオブジェクトを作成します。JSONオブジェクトの読み込みを開始および終了するには、beginObject()関数とendObject()関数を使用します。これらの関数呼び出しの間、データはペア(キー => 値)として読み込まれます。
JsonReader reader = new JsonReader();
reader.beginObject();
while (reader.hasNext()) {
	String name = reader.nextName();
	if (name.equals("key")) {
		String value = reader.nextString();
	}
}
reader.endObject();

Gsonのストリーミング処理は高速です。ただし、JSONデータの各ペア(キーと値のペア)は自分で処理する必要があります。

JAXBとは何ですか?

JAXBは Java ArchiXMLバインディングのアーキテクチャは、アノテーションを使用してXML文書を変換するライブラリです。 Java オブジェクトをXMLコンテンツに変換したり、その逆を行ったりできます。JAXBは仕様によって定義されているため、この標準のさまざまな実装を使用できます。

JAXBでは、以下の基本的なアノテーションをよく使用します。

  • @XmlRootElementこの注釈は XML ファイルの最上位のタグを指定するため、クラスの上に宣言されます。
  • @XmlElementWrapper: このアノテーションは、コレクションの周囲にラッパー XML 要素を作成します。
  • @XmlElementこの注釈は、オブジェクトのプロパティが XML ファイルの子タグになることを宣言します。
  • @XmlAttributeこの注釈は、オブジェクトのプロパティが周囲のタグの属性になることを宣言します。

一般的な実装は次のとおりです。まず、 JAXBコンテキスト を持つオブジェクト Myobject 変換するクラス。

JAXBContext jaxbContext = JAXBContext.newInstance(MyObject.class);

この JAXBコンテキスト オブジェクトには、XML コンテンツを Java オブジェクト、 アンマーシャラー.

Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();

どちらも同じ JAXBコンテキスト オブジェクトには、オブジェクトを変換するメソッドもあります。 Java オブジェクトを XML コンテンツに変換すると、 マーシャラー.

Marshaller marshallerObj = jaxbContext.createMarshaller();

⚠️ 警告: JAXBはJDKから削除されました Java 11。 に Java 11以降では、APIとランタイム実装をプロジェクトに明示的に追加します。例: jakarta.xml.bind:jakarta.xml.bind-api ととも​​に org.glassfish.jaxb:jaxb-runtime、そして注釈をインポートします jakarta.xml.bind.annotation javax.xml.bind.annotation.

XML を JSON に変換するにはどうすればよいですか?

XML から JSON への変換の例を以下のプラットフォームで実装します。以下のバージョンはスクリーンショットに使用されているものです。JDK の新しいリリースでは、 Eclipse、そしてGsonも同様に動作しますが、上記のJAXBに関する注記が適用されます。

  • OpenJDK 8 用 Ubuntu 18.04 x64。
  • Eclipse IDE 2019-03 (4.11.0) x64 Java のための開発 Ubuntu.
  • Gson 2.8.5。

ステップ1) プロジェクトを作成します。
新しいを作成します Java プロジェクト。

新しいを作成します Java プロジェクト。

ステップ2) プロジェクト名を設定してください。
プロジェクト名を次のように設定します XmlToJsonの例.

プロジェクト名を設定する

ステップ3) フォルダを作成します。
フォルダを作成する データ入力 2つのファイルを含む サンプル.xml (NAIST) と サンプル.json.

フォルダーデータの作成

まず、XMLを定義しましょう。 部門, 役割, Person プロパティ。

基本的な構造は、1つの部署に複数の役割があり、1つの役割に複数の担当者がいるというものです。下の図は、これらの関係を示しています。

オブジェクトの関係

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<root>
	<department>
		<roles>
			<role id="1">
				<position>head</position>
				<salary>10k</salary>
			</role>
			<role id="2">
				<position>manager</position>
				<salary>8k</salary>
			</role>
			<role id="3">
				<position>employee</position>
				<salary>5k</salary>
			</role>
		</roles>
		<persons>
			<person id="1">
				<name>Red</name>
				<role>1</role>
			</person>
			<person id="2">
				<name>Green</name>
				<role>2</role>
			</person>
			<person id="3">
				<name>Blue</name>
				<role>2</role>
			</person>
			<person id="4">
				<name>Yellow</name>
				<role>3</role>
			</person>
			<person id="5">
				<name>Brown</name>
				<role>3</role>
			</person>
		</persons>
	</department>
</root>

次に、同じ考え方を表現するJSONを定義します。フラットな人物リストが各役割の中にネストされた配列になることに注目してください。これはまさに変換コードが行う変換です。

{
	"roles": [
		{
			"id": "1",
			"position": "head",
			"salary": "10k",
			"persons": [
				{
					"id": "1",
					"name": "Red"
				}
			]
		},
		{
			"id": "2",
			"position": "manager",
			"salary": "8k",
			"persons": [
				{
					"id": "2",
					"name": "Green"
				},
				{
					"id": "3",
					"name": "Blue"
				}
			]
		},
		{
			"id": "3",
			"position": "employee",
			"salary": "5k",
			"persons": [
				{
					"id": "4",
					"name": "Yellow"
				},
				{
					"id": "5",
					"name": "Brown"
				}
			]
		}
	]
}

ステップ4) オブジェクトを定義します。
パッケージ内の対応するオブジェクトクラスを定義します .

オブジェクトクラスを定義する

役割.java

@XmlRootElement(name = "role")
public class Role {
	private String id;
	private String position;
	private String salary;
	public Role() {
		super();
	}
	public Role(String id, String position, String salary) {
		super();
		this.id = id;
		this.position = position;
		this.salary = salary;
	}
	@XmlAttribute(name = "id")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@XmlElement(name = "position")
	public String getPosition() {
		return position;
	}
	public void setPosition(String position) {
		this.position = position;
	}
	@XmlElement(name = "salary")
	public String getSalary() {
		return salary;
	}
	public void setSalary(String salary) {
		this.salary = salary;
	}
}

Person.java

@XmlRootElement(name = "person")
public class Person {
	private String id;
	private String name;
	private String role;
	public Person() {
		super();
	}
	public Person(String id, String name, String role) {
		super();
		this.id = id;
		this.name = name;
		this.role = role;
	}
	@XmlAttribute(name = "id")
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@XmlElement(name = "name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	@XmlElement(name = "role")
	public String getRole() {
		return role;
	}
	public void setRole(String role) {
		this.role = role;
	}
}

Department.java

@XmlRootElement(name = "department")
public class Department {
	private List<Role> roles;
	private List<Person> persons;
	public Department() {
		super();
	}
	public Department(List<Role> roles, List<Person> persons) {
		super();
		this.roles = roles;
		this.persons = persons;
	}
	@XmlElementWrapper(name = "roles")
	@XmlElement(name = "role")
	public List<Role> getRoles() {
		return roles;
	}
	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}
	@XmlElementWrapper(name = "persons")
	@XmlElement(name = "person")
	public List<Person> getPersons() {
		return persons;
	}
	public void setPersons(List<Person> persons) {
		this.persons = persons;
	}
}

XMLModel.java

@XmlRootElement(name = "root")
public class XMLModel {

	private Department department;

	public XMLModel() {
		super();
	}

	public XMLModel(Department department) {
		super();
		this.department = department;
	}

	@XmlElement(name = "department")
	public Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

}

ステップ5) ライブラリを設定してください。
Gson 2.8.5 ライブラリを追加して設定します。 Java ビルドパス。

ライブラリ Gson をセットアップする

ライブラリGson 2.8.5を追加 Java ビルドパス

プロジェクトが使用する 達人 手動で追加したjarファイルではなく、同じライブラリが依存関係として宣言されています。ここではスクリーンショットに合わせてバージョン2.8.5を固定していますが、それ以降のGsonリリースでもこの例で同様に動作します。

<dependencies>
    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- required on Java 11 and later -->
    <dependency>
        <groupId>jakarta.xml.bind</groupId>
        <artifactId>jakarta.xml.bind-api</artifactId>
    </dependency>
    <dependency>
        <groupId>org.glassfish.jaxb</groupId>
        <artifactId>jaxb-runtime</artifactId>
    </dependency>
</dependencies>

XMLメッセージを変換する Java JAXB を使用するオブジェクト

まず、パッケージ内の実行クラスを定義します。 サービス.

実行クラスを定義する

最初のプロセスの最初のステップでは、JAXBのアンマーシャリング技術を使用します。

アンマーシャリングにより、クライアントアプリケーションはXMLデータをJAXB派生形式に変換する機能を持つ Java オブジェクト。

関数を定義します getObjectFromXmlFile XML ファイルをアンマーシャリングして Java オブジェクト。この関数はクラスで定義されています。 XMLサービス.

public XMLModel getObjectFromXmlFile(String filePath) {
	try {
		File file = new File(filePath);
		JAXBContext jaxbContext = JAXBContext.newInstance(XMLModel.class);

		Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller();
		XMLModel root = (XMLModel) jaxbUnmarshaller.unmarshal(file);

		return root;
	} catch (JAXBException e) {
		e.printStackTrace();
		return null;
	}
}

クラス内で上記のコードを呼び出します XmlToJsonService.

XMLService xmlService = new XMLService();
XMLModel xmlModel = xmlService.getObjectFromXmlFile(filePathIn);

Department department = xmlModel.getDepartment();
List<Role> roles = department.getRoles();
List<Person> persons = department.getPersons();

この時点でXMLファイルは3つになりました Java メモリ上にオブジェクトが格納されます。次のステップでは、それらをJSON形式で出力します。

変換 Java Gson を使用してオブジェクトを JSON メッセージに変換する

このステップでは、関数を定義します。 writeDataToJsonFile JSONファイルにデータを書き込む。この関数はクラス内で定義されています。 JsonService.

JSONオブジェクトのリストを書き込むには、以下の関数を使用することに注意してください。 beginArray() (NAIST) と endArray()これらの2つの呼び出しの間に、各JSONオブジェクトを書き込みます。

public void writeDataToJsonFile(String filePath, List<Role> roles, List<Person> persons) {
	try {
		JsonWriter writer = new JsonWriter(new FileWriter(filePath));
		writer.setIndent("    ");
		writer.beginObject();
		writer.name("roles");
		writer.beginArray();
		for (Role role : roles) {
			writer.beginObject();
			writer.name("id").value(role.getId());
			writer.name("position").value(role.getPosition());
			writer.name("salary").value(role.getSalary());
			writer.name("persons");
			writer.beginArray();
			for (Person person : persons) {
				if (person.getRole().equalsIgnoreCase(role.getId())) {
					writer.beginObject();
					writer.name("id").value(person.getId());
					writer.name("name").value(person.getName());
					writer.endObject();
				}
			}
			writer.endArray();
			writer.endObject();
		}
		writer.endArray();
		writer.endObject();
		writer.close();
	} catch (IOException e) {
	}
}

クラス内で上記のコードを呼び出します XmlToJsonService.

JsonService jsonService = new JsonService();
jsonService.writeDataToJsonFile(filePathOut, roles, persons);

これが最初の処理です。内側のループでは、各人物を現在の役割IDと照合し、それによってフラットなXML人物リストがネストされたJSON配列に変換されます。

JSONメッセージを変換する Java Gson を使用したオブジェクト

2番目のプロセスの最初のステップでは、関数を定義します。 getDataFromJsonFile JSONファイルからデータを読み込む。この関数はクラスで定義されています。 JsonService.

JSONオブジェクトのリストを読み込むには、以下の関数を使用します。 beginArray() (NAIST) と endArray()これらの2つの呼び出しの間で、各JSONオブジェクトを読み取ります。

public void getDataFromJsonFile(String filePath, List<Role> roles, List<Person> persons) {
	try {
		JsonReader reader = new JsonReader(new FileReader(filePath));
		reader.beginObject();
		while (reader.hasNext()) {
			String nameRoot = reader.nextName();
			if (nameRoot.equals("roles")) {
				reader.beginArray();
				while (reader.hasNext()) {
					reader.beginObject();
					Role role = new Role();
					while (reader.hasNext()) {
						String nameRole = reader.nextName();
						if (nameRole.equals("id")) {
							role.setId(reader.nextString());
						} else if (nameRole.equals("position")) {
							role.setPosition(reader.nextString());
						} else if (nameRole.equals("salary")) {
							role.setSalary(reader.nextString());
						} else if (nameRole.equals("persons")) {
							reader.beginArray();
							while (reader.hasNext()) {
								reader.beginObject();

								Person person = new Person();
								person.setRole(role.getId());

								while (reader.hasNext()) {
									String namePerson = reader.nextName();
									if (namePerson.equals("id")) {
										person.setId(reader.nextString());
									} else if (namePerson.equals("name")) {
										person.setName(reader.nextString());
									}
								}
								persons.add(person);
								reader.endObject();
							}
							reader.endArray();
						}
					}
					roles.add(role);
					reader.endObject();
				}
				reader.endArray();
			}
		}
		reader.endObject();
		reader.close();
	} catch (IOException e) {

	}
}

クラス内で上記のコードを呼び出します XmlToJsonService.

JsonService jsonService = new JsonService();
List<Role> roles = new ArrayList<>();
List<Person> persons = new ArrayList<>();

jsonService.getDataFromJsonFile(filePathIn, roles, persons);

変換 Java JAXB を使用してオブジェクトを XML メッセージに変換する

このステップでは、JAXBのマーシャリング技術を使用します。

マーシャリングは、クライアントアプリケーションにJAXB派生の Java オブジェクト ツリーを XML データに変換します。

関数を定義します parseObjectToXml を統率する Java オブジェクトを XML メッセージに変換します。この関数はクラスで定義されています。 XMLサービス.

public void parseObjectToXml(String filePath, XMLModel xmlModel) {
	try {
		JAXBContext contextObj = JAXBContext.newInstance(XMLModel.class);

		Marshaller marshallerObj = contextObj.createMarshaller();
		marshallerObj.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);

		marshallerObj.marshal(xmlModel, new FileOutputStream(filePath));
	} catch (JAXBException je) {
		System.out.println("JAXBException");
	} catch (IOException ie) {
		System.out.println("IOException");
	}
}

クラス内で上記のコードを呼び出します XmlToJsonService.

XMLService xmlService = new XMLService();
XMLModel xmlModel = new XMLModel();

Department department = new Department();
department.setRoles(roles);
department.setPersons(persons);

xmlModel.setDepartment(department);

xmlService.parseObjectToXml(filePathOut, xmlModel);

これが2番目のプロセスです。生成されたファイルは元のsample.xmlと一致しており、往復処理で全ての値が保持されたことが確認できます。

JSONをXMLに変換する方法 Java モデルクラスなしで?

上記のアプローチは、構造が既知で安定している場合に適切な選択肢です。なぜなら、注釈付きクラスは構造を文書化しているからです。tract. 構造が不明な場合や頻繁に変更される場合は、汎用コンバータの方が速い。

その org.json ライブラリは、モデルクラスを使用せずに、2行で変換を実行します。

import org.json.JSONObject;
import org.json.XML;

public class QuickConverter {

    public static void main(String[] args) {
        String str = "{\"username\":\"guru99user\",\"email\":\"guru99user@mail.com\"}";

        JSONObject json = new JSONObject(str);
        String xml = XML.toString(json);

        System.out.println(xml);
    }
}

出力:

<username>guru99user</username><email>guru99user@mail.com</email>

一般的なルートではルート要素も属性も生成されないことに注意してください。 XML.toString(json, "root") 通常、 が必要です。以下の表は、2つのアプローチを並べて示しています。

基準 GsonとJAXB org.json 汎用変換
必要なモデルクラス はい いいえ
構造に対する制御 属性を含む完全版 限定、要素のみ
レシャping データ 入れ子構造の人物で示されているように、可能です。 ありえない
コード行数 その他にもたくさんのグーグルの ツー
ベスト 安定した、文書化されたスキーマ アドホックまたは未知の構造

JAXBはXMLデータを読み込み、GsonはそれをJSONに書き込み、逆のパスではGsonを使用してデータを読み込みます。 JSONの JAXBがデータをXMLに書き戻す間、データは保持されます。さらに詳しく知りたい場合は、以下を参照してください。 XML 基礎、より広範な Java チュートリアル, ジャスパーレポートこれは、両方の形式をレポートデータソースとして利用します。

よくあるご質問

JAXBはJDKから削除されました Java 11. jakarta.xml.bind API を jaxb-runtime などのランタイムとともに追加し、javax から jakarta へのインポートを更新します。

いいえ。GsonはJSONのみを扱います。XMLはまず変換する必要があります。 Java Gsonがシリアライズする前に、JAXBまたはJackson XMLなどの別のパーサーを介してオブジェクトを処理する必要があります。

XmlElement は値を含む子タグを生成しますが、XmlAttribute は親タグの開始タグ内に値を配置します。属性はネストされた構造を保持できません。

ストリーミングはメモリ使用量を低く抑え、出力構造を入力クラスと異なるものにすることを可能にします。これはまさに、ここで人物が役割の中にネストされている場合に起こることです。

はい、サンプルXMLドキュメントから取得しました。コレクションのラッパー注釈を確認してください。生成されたクラスではXmlElementWrapperが省略され、フラットな構造が生成されることがよくあります。

JSONとその行区切り形式が主流となっているのは、それらが直接マッピングされるからである。 Python 辞書とストリームを効率的に処理します。XMLは、従来のエンタープライズシステムがソースデータを提供する場合に依然として使用されます。