14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

UiPathでJSON文字列を自在に生成する

Last updated at Posted at 2021-03-29

#はじめに
UiPathを使用してAPI連携メインのロボットを作成する際、APIコールに必要な複雑なJSONを作成する方法に悩んだため、備忘用に投稿しました。
本記事はあくまでも数ある方法の中での一つでしかなく、これが正解だと言いたいわけではないことをまず申し上げておきます。

なお本記事は、@masatomix 様の下記投稿を先にご覧になったほうが理解しやすいと思います。(非常にわかりやすい記事で参考にさせていただきました)

本記事は上記の続編という扱いで見ていただければ幸いです。

#まずは結論から
とりあえず下記をおさえておけばOKです!次項から詳しく記載します。

  • JSONの {変数名, 値} は、Dictionary の {TKey, TValue} で表現
  • JSONの を配列にしたいときは、List で表現
  • Dictonary型変数 → JSON文字列への変換は
    Newtonsoft.Json.JsonConvert.SerializeObject( Dictionary型変数 )

※Newtonsoft.Json.JsonConvert.SerializeObject についてはココを参照

#本記事のゴール
本記事を理解すれば、以下のようなJSONを難なく作れるようになれます!(のはず…)

これを作れるようになろう
{
	"families": [
		{
			"name": "Bob",
			"age": 24,
			"favorite_color": [
				"blue",
				"green"
			],
			"active": true
		},
		{
			"name": "Lisa",
			"age": null,
			"favorite_color": [
				"red",
				"purple"
			],
			"active": false
		}
	]
}

では早速いってみましょう!

#前提(開発環境とか)
####UiPath

  • Studio Pro 2021.4.0-beta.158(Community License)

####使用パッケージ

Package Version 手動追加
UiPath.System.Activities 20.10.4
Microsoft.Activities.Extensions 2.0.6.9
UiPath.WebAPI.Activities 1.6.0

※パッケージの手動追加が必要

#まずは基本のJSON作成(JSON値が文字列編)

本項は @masatomix 様の 投稿 と内容が重複しますが、基本となるため本記事でも取り上げます。
まずは以下JSONの作成方法を記載します。

作りたいJSON
{
	"name": "Bob",
	"email": "bob@example.com"
}

このようなシンプルな JSON であれば String 変数をゴリゴリいじって作成してもいいのですが、複雑な JSON になればなるほど実装内容がわかりづらくなる傾向があります。
そこで JSON は、以下のイメージで Dictionary を作成 → 文字列に変換、という実装をするとわかりやすくなります。

  • 作成する Dictionary
Key(String) Value(String)
"name" "Bob"
"email" "bob@example.com"

では Studio で実装してみます。

###Studio作成例

変数設定
Studio_変数設定.png

ワークフロー
image.png

解説

Dim jsonDic = New Dictionary(Of String, String)

上記変数を Studio 上で定義および初期化しているので、Add to dictionary アクティビティで要素を2つ追加します。

  • 1つ目の要素:Key="name", Value="Bob"
    image.png

  • 2つ目の要素:Key="email", Value="bob@example.com"
    image.png

これで Dictionary に要素を2つ追加することが出来ました。


※補足※
Add to dictionary アクティビティは Microsoft.Activities.Extensions パッケージをインストールしないと使えません。
「大人の事情でデフォルトのパッケージしか使えない:sob:」という方は、代入 アクティビティや、 Invoke Method アクティビティで Dictionary.Add メソッドを使うと良いでしょう。

個人的に Dictionary に要素を追加する際は、閲覧性の良さから Add to dictionary アクティビティを好んで使っています。


その後、JSON をデシリアライズ アクティビティを実行します。
Jsonをデシリアライズ.png
image.png

このアクティビティは、JSON文字列を入力すると、それに対応するJsonオブジェクト(JObject型)の変数を返してくれます。

Json文字列 プロパティは、以下のように設定して下さい。
Newtonsoft.Json.JsonConvert.SerializeObject(jsonDic)

上記メソッドは、引数に指定した Dictionary を JSON 文字列化して返してくれます。ただし出力されるのは整形されていない JSON 文字列です。ログで見てわかりやすくするため、今回は JSON 整形の目的のみで JSON をデシリアライズ アクティビティを実行しています)

本アクティビティの出力結果は JObject 型で返ってきます。(JObject の詳細はココを参照
出力結果は jsonObj 変数に入っているので、この内容を ToString で見てみます。
結果はいかに...?

メッセージをログ.png

image.png

想定どおりのJSON文字列を作成することができました:clap:
Dictionary を使用することで、

  • Key → JSONの変数名
  • Value → JSONの値

という変換が簡単にできる、というのが基本となる重要なポイントです:point_up:

#JSON値が数値の場合
では欲しいJSON値が数値の場合、どうしたらいいでしょうか?

作りたいJSON
{
	"age": 24
}

JSON値が数値の場合でも基本は同じで、Dictionary を作成 → 文字列に変換 という流れは変わりません。
先ほどの例との変更箇所は、Dictionary<TKey, TValue>TValue の型が String → Int32 に変わるのみ です。

Key(String) Value(Int32)
"age" 24

では Studio で実装してみます。

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説

Dim jsonDic = New Dictionary(Of String, Int32)

上記変数をStudio上で定義および初期化しているので、Add to dictionary アクティビティで要素を1つ追加します。

  • 1つめの要素:Key="age", Value=24
    image.png

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

想定通りのJSONが作成できました!
Dictionary の TValue の型を Int32 で定義したので、それに合わせて出力される文字列が 24 となりダブルコーテーションで括られず、JSON仕様的に正しい数値型として出力されている のがポイントです:point_up:

#JSON値が真偽値の場合
欲しいJSON値が真偽値の場合でも、対応方法はまったく同じです。

作りたいJSON
{
	"active": true
}

今回も同様に、欲しいJSON値の型に合わせて Dictionary<TKey, TValue>TValue の型を Boolean に変えるのみ です。

Key(String) Value(Boolean)
"active" true

ではStudioで実装してみます。

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説

Dim jsonDic = New Dictionary(Of String, Boolean)

上記変数をStudio上で定義および初期化しているので、Add to dictionary アクティビティで要素を1つ追加します。

  • 1つめの要素:Key="active", Value=True
    image.png

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

こちらも想定通りですね!
Dictionary の TValue の型を Boolean で定義したので、それに合わせて出力される文字列が true となりダブルコーテーションで括られず、JSON仕様的に正しい真偽値として出力されている のがポイントです:point_up:

#JSON値に複数の型が必要な場合
ここからが実践編です。
以下のように、APIのパラメータに複数のJSON値の型を指定しなければならないケースがあります。

作りたいJSON
{
	"name": "Bob",
	"age": 24,
	"active": true
}

今までは欲しいJSON値の型に合わせて Dictionary<TKey, TValue>TValue の型を定義していましたが、複数の型が必要な場合は Object 型で定義 します。

Key(String) Value(Object)
"name" "Bob"
"age" 24
"active" true

ではStudioで実装してみます。

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説

Dim jsonDic = New Dictionary(Of String, Object)

上記変数をStudio上で定義および初期化しているので、Add to dictionary アクティビティで要素を3つ追加します。

  • 1つめの要素:Key="name", Value="Bob" (String)
    image.png
  • 2つめの要素:Key="age", Value=24 (Int32)
    image.png
  • 3つめの要素:Key="active", Value=True (Boolean)
    image.png

Dictionary を Object 型で定義したことで、変数値に複数の型を入力できているのがポイントです:point_up:

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

バッチリですね!
このように 変数値に複数の型が必要な場合は、Dictionary の TValueObject 型で定義 すると目的のJSONを簡単に作ることが出来ます。

#JSON値が配列の場合
JSON値には仕様上、以下のように配列を指定することができます。

作りたいJSON
{
	"favorite_colors": [
		"red",
		"green",
		"blue"
	]
}

冒頭で記載したとおり、配列は List<T> で表現します。
上記のJSON値が必要な場合、Dictionary の TValueList<String> 型で定義すると目的のJSONを作成可能です。

Key(String) Value( List<String> )
"favorite_colors" {"red", "green", "blue"}

ではStudioで実装してみます。

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説

' favorite_colors の値用の List 型変数
Dim listColors = New List(Of String)

' JSON 作成用の Dictionary 型変数
Dim jsonDic = New Dictionary(Of String, List(Of String))

上記変数をStudio上で定義および初期化しています。

まずは listColors 変数に対して、"red" "green" "blue" の値を3つ追加します。
List<String> 型の変数へ値を追加する方法はいくつかありますが、今回はデフォルトで用意されている コレクションに追加(Add To Collection) アクティビティを使ってみます。

  • "red" を追加
    image.png
    image.png

  • "green" を追加
    image.png
    image.png

  • "blue" を追加
    image.png
    image.png

今までと同様、上記 listColors 変数を Add to dictionary アクティビティで追加します。
image.png

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

配列の値がブラケット([])付きで出力されました!
このように 変数値に配列が必要な場合、Dictionary の TValueList<T> 型で定義 すると目的のJSONを簡単に作ることが出来ます。


※補足※
「配列は List<T> で表現する」と記載しましたが、直接配列を定義しても同じ結果を取得することができます。
今回の例で言うと、List<String> ではなく String(2) という String型の配列でも実現可能です。

どちらが正解というわけではありませんが、直接配列を定義すると要素数の定義等で少し実装がややこしくなるため、個人的には List<T> で実装したほうがシンプルになるかと考えています。


#JSON値が オブジェクト型 の場合
以下のように、JSON値にはオブジェクト型も指定可能です。

作りたいJSON
{
	"user_info": {
		"user_id": "A1234567",
		"user_name": "Bob"
	}
}

若干トリッキーですが、こういったケースは Dictionary の値に、更に Dictionary を格納する ことで対応可能です。
以下のイメージで変数を定義すればOKです。

Key(String) Value( Dictionary<String, String> )
"user_info" Dictionary<String, String>(←"user_id" と "user_name" を格納)

若干イメージ湧きづらいかもしれませんね。
ではStudioで実装してみます。

変数設定
image.png

ワークフロー
image.png

解説

' Bob の情報を格納する Dictionary
Dim BobDic = New Dictionary(Of String, String)

' Bob 用の Dictionary 自体を値に持つ、Dictionary
' (TValue は Object の定義でも可)
Dim jsonDic = New Dictionary(Of String, Dictionary(Of String, String))

上記変数をStudio上で定義および初期化しています。

まずはDictionary変数 BobDic に、Bob専用の情報を2つ格納します。

  • 1つ目の要素:Key="user_id", Value="A1234567"
    image.png

  • 2つ目の要素:Key="user_name", Value="Bob"
    image.png

次にそれを包み込むような形で、Dictionary 変数 jsonDic の値に上記 BobDic を格納します。

  • Key="user_info", Value=BobDic
    image.png

完成した Dictionary 変数 jsonDicを、JSON文字列に自動変換:point_down:
image.png

想定通りのJSONが出力されました!
JSONの仕様上、オブジェクトは階層構造を持つことができます。
Dictionary の値の中に、更に Dictionary を格納することで実現可能、ということが今回の重要なポイントです:point_up:

#JSON値が null の場合
JSON値には仕様上、null を指定することもできます。

###JSON値が文字列型の場合に null が必要なケース

作りたいJSON
{
	"first_name": "Bob",
	"last_name": null
}

VB.NET での null の表現は Nothing ですから、必要な Dictionary は以下になる、というのは想像が付くかと思います。

Key(String) Value(String)
"first_name" "Bob"
"last_name" Nothing

ではStudioで実装してみます。

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説

Dim jsonDic = New Dictionary(Of String, String)

上記変数をStudio上で定義および初期化しているので、Add to dictionary アクティビティで要素を2つ追加します。

  • 1つめの要素:Key="first_name", Value="Bob"
    image.png

  • 2つめの要素:Key="last_name", Value=Nothing
    image.png

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

想定通りのJSONが作成できました!
Dictionary の Value 値に Nothing を代入すると、JSON文字列に変換したときに null と正しく表現されているのがポイントです:point_up:

JSON値が数値型の場合に null が必要なケース

数値型の場合は少し注意が必要です。例えば以下のケースで考えてみます。

作りたいJSON
{
	"height": 173,
	"weight": null
}

今までの記事を参考にして、必要な Dictionary は以下で定義してみます。

Key(String) Value(Int32)
"height" 173
"weight" Nothing

Studio での実装例は前項の String 型とほぼ同じであるため割愛しますが、注目したいのは以下の出力結果です。
image.png

なんと weight がゼロで出力 されてしまいました…これは想定外ですね。
Int32型の変数に Nothing を代入した結果は、0 という文字列で出力されてしまう
ということを抑えておく必要があります。

対策として、以下の形で Dictionary を定義すると想定通りのJSONを取得することが出来ます。
TValue の型を Int32 ではなく、Object で定義する)

Key(String) Value(Int32 Object)
"height" 173
"weight" Nothing

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

weight の値が null となりました、想定通りのJSONになりましたね!:clap:

###JSON値が真偽値の場合に null が必要なケース
真偽値の場合でも、数値型と同じ問題が発生します。例えば以下のケースです。

作りたいJSON
{
	"active": true,
	"marriage": null
}

必要な Dictionary は以下で定義してみます。

Key(String) Value(Boolean)
"active" true
"marriage" Nothing

こちらも Studio での実装例は割愛しますが、注目したいのは以下の出力結果です。
image.png

marriage が false で出力 されてしまいました…。
Boolean型の変数に Nothing を代入した結果は、false という文字列で出力されてしまう
ということも合わせて抑えておく必要があります。

対策として、以下の形で Dictionary を定義すると想定通りのJSONを取得することが出来ます。
TValue の型を Boolean ではなく、Object で定義する)

Key(String) Value(Boolean Object)
"active" true
"marriage" Nothing

上記 Dictionary を、JSON文字列に自動変換:point_down:
image.png

marriageの値が null となりました!:clap:

###null値が必要な場合のまとめ
変数へ Nothing 代入後、JSON文字列へ変換した際に出力される文字列をまとめます。

変数の型 JSON変換後の値 結果
String null OK
Int32 0 NG
Boolean false NG
Object null OK

以上のことから、**JSON値に null が必要な場合、Dictionary の TValue の型は Object 型で定義**しておくと良いでしょう。

#最終章:目的のJSONを作成してみよう

ここまでの内容を抑えておけば、冒頭で触れた目的のJSONが作成可能になるはずです。

作りたいJSON
{
	"families": [
		{
			"name": "Bob",
			"age": 24,
			"favorite_color": [
				"blue",
				"green"
			],
			"active": true
		},
		{
			"name": "Lisa",
			"age": null,
			"favorite_color": [
				"red",
				"purple"
			],
			"active": false
		}
	]
}

上記JSONを分解して必要な変数(と型)を割り当てられればOKなのですが、この複雑度だと頭の中だけで考えるのはツラくなってきますので図に起こしてみます。
左側が作成したいJSON、右側が対応する変数と型を定義した図です。

image.png

実務を想定すると「Bob用とLisa用で変数を分ける」という実装は有り得ないのですが、今回は話をシンプルにするためにあえて変数を分けています。
図を整理すると、以下の形になります。

  • ①と②:Bob一人分の情報を格納する変数
  • ③と④:Lisa一人分の情報を格納する変数
  • ⑤Bob と Lisa をまとめる List
  • ⑥全部をまとめる Dictionary

ここまで整理できれば Studio で実装が可能になります。
早速やってみます!

###Studio作成例

変数設定
image.png

ワークフロー
image.png

解説
上記ワークフローだけだと全然わかりませんね(笑)
一つずつ記載していきます。

####Bobの情報作成(変数①と②)

まずは Dictionary である dicBob 変数に以下の値を追加します。

Key(String) Value(Object) 備考
"name" "Bob"
"age" 24
  • 1つ目の要素 Key="name", Value="Bob"
    image.png

  • 2つ目の要素 Key="age", Value=24
    image.png

次に List である favColorsBob に、Bob の好きな色を追加します。
image.png

  • 1つ目の要素 "blue"

image.png
image.png

  • 2つ目の色 "green"

image.png
image.png

作成したList変数 favColorsBob を、Bobの情報を格納するDictionary dicBob に追加します。

Key(String) Value(Object) 備考
"name" "Bob"
"age" 24
"favorite_color" {"blue", "green"}

image.png

最後に active=True を dicBob に追加し、Bob 用の情報は全て格納完了となります。

Key(String) Value(Object) 備考
"name" "Bob"
"age" 24
"favorite_color" {"blue", "green"}
"active" True

image.png

以上で Bob 一人分の情報を格納する Dictionary 変数である dicBob が完成しました!

####Lisa の情報作成(変数③と④)

こちらは Bob の情報作成方法とほぼ同じであるため、実装内容は割愛します。
最終的に以下の形の Dictionary 変数 dicLisa が完成していればOKです!

Key(String) Value(Object)
"name" "Lisa"
"age" Nothing
"favorite_color" {"red", "purple"}
"active" False

####Bob と Lisa をまとめる List(変数⑤)

次にList型変数 familyList に、Bob情報(dicBob)と、Lisa情報(dicLisa)を格納します。
image.png

  • 1つ目の要素 dicBob

image.png
image.png

  • 2つ目の要素 dicLisa

image.png
image.png

####全部をまとめる Dictionary(変数⑥)

最後に今まで作成した変数をまとめる Dictionary型変数 jsonDic に値を格納します。

image.png

最後にこの jsonDic を、JSON文字列に自動変換:point_down:
image.png

目的のJSON文字列を作成することができましたね:clap:

#最後に

Dicationary と List の組み合わせだけで、JSONを自在に作成可能なことがわかりました!
もし他にもっとスマートなやり方等をご存じでしたら、ご指摘いただけますと幸いです。

#参考にしたサイト、記事
下記の素晴らしい記事を参考にし、UiPathで色々と検証させていただきました。
ありがとうございます:bow_tone1:

14
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?