12.3.1 JSON→XSD変換の規則
JSON→XSD変換の規則について説明します。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
false |
<xs:element name="root" type="xs:boolean"/> |
|
null |
<xs:element name="root" type="xs:string" nillable="true"/>※ |
|
true |
<xs:element name="root" type="xs:boolean"/> |
|
123 |
<xs:element name="root" type="xs:decimal"/> |
|
"abc" |
<xs:element name="root" type="xs:string"/> |
|
[ "abc", "def" ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> |
|
{ "field1":"abc", "field2":"def" } |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> |
注※ type属性は要素によって異なります。
XML宣言およびschema要素については,「12.3.1(1) XML宣言およびschema要素の変換」を参照してください。
- 〈この項の構成〉
(1) XML宣言およびschema要素の変換
JSON→XSD変換で生成するXSDのXML宣言およびschema要素は,次のように出力されます。
<?xml version="1.0" encoding="UTF-8"?> <xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:csc="http://www.hitachi.co.jp/soft/xml/cosminexus/csc/jsonxml"> </xs:schema>
(2) minOccurs属性の変換
ルート要素および配列要素以外のelement要素には,minOccurs属性に0(省略可)を設定します。ルート要素および配列要素のelement要素には,minOccurs属性はデフォルトの1が適用されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
"abc" |
<xs:element name="root" type="xs:string"/> |
|
[ "abc" ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> |
|
{ "field1":"v1", "field2":123 } |
<xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string" /> <xs:element name="field2" minOccurs="0" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> |
(3) 要素名の自動生成
JSON形式データでは,JSON Objectのフィールド以外にフィールド名(要素名)は存在しませんが,XMLでは,要素名(要素タグ)が必要です。そのため,JSON→XSD変換では,要素名を次のように自動生成します。
-
ルート要素の要素名:root
-
ルート要素以外の無名要素名:unnamed_<連番>
JSON→XSD変換の結果を編集し,読みやすい要素名に変更することをお勧めします。
自動生成する要素名は,JSONtoXSDConverterFactory.getConverter(Map<Object,Object> options)のoptionsパラメタで変更できます。
|
対象 |
optionsパラメタkey |
デフォルト値 |
|---|---|---|
|
ルート要素の要素名 |
"rootTag" |
"root" |
|
ルート要素以外の無名要素名 |
"unnamedTagPrefix" |
"unnamed_" |
(4) 1次元配列のJSON→XSD変換
JSON形式データでは,配列に複数のデータ型の要素を含めることができます。JSON→XSD変換では,配列内にあるデータ型をすべてchoice要素内のelement要素に変換します。
ただし,JSONオブジェクトの1次元配列フィールドで,各要素のデータ型が単一の場合は,maxOccurs="unbounded"を指定した<element>に変換されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ true, null, false, 123, "abc", { "field1":"v1", "field2":"v2" }, [ "def", "hij" ] ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1" nillable="true" type="xs:boolean"/> <xs:element name="unnamed_2" nillable="true" type="xs:string"/> <xs:element name="unnamed_3" nillable="true" type="xs:decimal"/> <xs:element name="unnamed_4" nillable="true"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="unnamed_6" nillable="true" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_5" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
多次元配列に対応するJSON→XSD変換については,「12.3.1(5) 多次元配列のJSON→XSD変換」を,Object型の配列要素については,「12.3.1(6) 配列要素がJSON Objectの場合のJSON→XSD変換」を参照してください。
(5) 多次元配列のJSON→XSD変換
多次元配列の各次元のデータ型は1つのchoice要素内に含まれます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ [true,false], [123, "abc"], [ { "field1":"v1", "field2":"v2" }, "def" ], [ { "field1":"v3", "field2":"v4" } ] ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_2" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="unnamed_1" type="xs:boolean"/> <-- true, false --> <xs:element name="unnamed_3" type="xs:decimal"/> <-- 123 --> <xs:element name="unnamed_4" type="xs:string"/> <-- "abc", "def" --> <xs:element name="unnamed_5"> <-- {...} --> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string" /> <xs:element name="field2" minOccurs="0" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
(6) 配列要素がJSON Objectの場合のJSON→XSD変換
配列要素に次の条件を満たす複数のJSON Objectが存在する場合,各JSON Objectのフィールドをマージし,1つのsequence要素にまとめて定義されます。
-
条件1:同名かつ同データ型のフィールドを持つJSON Object
-
条件2:同名のフィールドを持たないJSON Object
次の例では,field1は条件1に合致し,field2,field3,field4は条件2に合致するため,3つのObjectをマージして1つのsequence要素にまとめて定義されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ { "field1":"v1", "field2":"v2" }, { "field1":"v3", "field3":123 }, { "field1":"v4", "field4":true } ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:string"/> <xs:element name="field3" minOccurs="0" type="xs:decimal"/> <xs:element name="field4" minOccurs="0" type="xs:boolean"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
複数の配列要素Objectが次の条件に合致する場合は,別の異なるsequence要素を持つ,別のelement要素として定義されます。
-
条件3:異なるデータタイプの同名フィールドが存在する
次の例では,field1は条件1に合致し,field2は条件3に合致するため,それぞれのObjectは異なるsequence要素を持つelement要素として定義されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ { "field1":"v1", "field2":"v2" }, { "field1":"v3", "field2":123 }, { "field1":"v4", "field2":true } ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="unnamed_2"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="unnamed_3"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:boolean"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
JSON→XSD変換では,これらの判定は再帰的に行われます。
次の例では,JSON Objectはfield2のsub2のデータ型が異なるため,異なるelement要素として定義されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ { "field1": "v1", "field2":{ "sub1":"s1", "sub2":"s2" } }, { "field1":"v2", "field2":{ "sub1":"s3", "sub2":123 } } ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="sub1" minOccurs="0" type="xs:string"/> <xs:element name="sub2" minOccurs="0" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="unnamed_2" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0"> <xs:complexType> <xs:sequence> <xs:element name="sub1" minOccurs="0" type="xs:string"/> <xs:element name="sub2" minOccurs="0" type="xs:decimal"/> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
JSON Objectをマージするかどうかの判定は,JSON Objectの出現順に実行され,最初にマージ可能と判定されたJSON Object同士をマージします。
例えば,次の例では,Object配列要素の1番目のObjectと2番目のObject,2番目のObjectと3番目のObjectは,それぞれマージできますが,出現順序が早い1番目のObjectと2番目のObjectをマージし,3番目のObjectは独立したelement要素として定義されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
[ { "field1":"v1", "field2":"v2" }, { "field1":"v3", "field3":true }, { "field2":123, "field3":false } ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string" /> <xs:element name="field2" minOccurs="0" type="xs:string" /> <xs:element name="field3" minOccurs="0" type="xs:boolean" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="unnamed_2"> <xs:complexType> <xs:sequence> <xs:element name="field2" minOccurs="0" type="xs:decimal" /> <xs:element name="field3" minOccurs="0" type="xs:boolean" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
注 XML宣言とschema要素は省略しています。
(7) nullの変換
nullは対象要素のnillable属性にtrueが設定されます。配列要素の場合,配列要素内のelement要素のすべてのnillable属性にtrueが設定されます。対象要素が特定できない場合は,string型の要素を生成し,nillable属性にtrueが設定されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
null |
<xs:element name="root" type="xs:string" nillable="true"/> |
|
[ null ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1" type="xs:string" nillable="true"/> </xs:choice> </xs:complexType> </xs:element> |
|
[ null, true, "abc" ]
|
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1" type="xs:boolean" nillable="true"/> <xs:element name="unnamed_2" type="xs:string" nillable="true"/> </xs:choice> </xs:complexType> </xs:element> |
|
[ { "field1":"v1", "field2":"v2" }, { "field1":null, "field2":"v2" } ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="unnamed_1"> <xs:complexType> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string" nillable="true"/> <xs:element name="field1" minOccurs="0" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
(8) mixed contentsの変換
フィールド名#textを持つJSON Objectは,mixed contentのcomplexType要素として生成されます。mixed contentのcomplexType要素のsequence要素は,#text以外のフィールドを子要素として持ちます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
{ "field1":"v1", "field2":"v2", "#text":"v3" } |
<xs:element name="root" > <xs:complexType mixed="true"> <xs:sequence> <xs:element name="field1" minOccurs="0" type="xs:string"/> <xs:element name="field2" minOccurs="0" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> |
mixed contents内の要素データ(#textで指定されるデータ)は,データ変換のマッピング対象外です。
(9) 別名のフィールドの変換
JSON Objectのフィールド名が,XMLの要素タグとして使用できない場合,フィールド名の使用できない文字を「_(アンダースコア)」に置き換え,csd:jsonfield属性に元のフィールド名が設定されます。置き換えた要素名が重複する場合,末尾に連番が付与されます。
|
入力するJSONファイルの定義 |
生成するXSD(XMLスキーマ) |
|---|---|
|
{ "<field1>":"v1", "2field":"v2", "3field":"v3" } |
<xs:element name="root" > <xs:complexType mixed="true"> <xs:sequence> <xs:element name="_field1_" minOccurs="0" type="xs:string" csc:jsonfield="<field1> "/> <xs:element name="_field" minOccurs="0" type="xs:string" csc:jsonfield="2field"/> <xs:element name="_field1" minOccurs="0" type="xs:string" csc:jsonfield="3field"/> </xs:sequence> </xs:complexType> </xs:element> |