12.3.2 JSON→XML変換の規則
JSON→XML変換の規則について説明します。
|
入力するJSONファイルの定義 |
対応するXSD(XMLスキーマ) |
XML変換結果 |
|---|---|---|
|
false |
<xs:element name="root" type="xs:boolean"/> |
<root>false</root> |
|
null |
<xs:element name="root" type="xs:string" nillable="true"/>※1 |
<root xsi:nil="true"/> |
|
true |
<xs:element name="root" type="xs:boolean"/> |
<root>true</root> |
|
123 |
<xs:element name="root" type="xs:decimal"/> |
<root>123</root> |
|
"abc" |
<xs:element name="root" type="xs:string"/> |
<root>abc</root> |
|
{ "field":"value" }
|
<xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> |
<root> <field>value</field> </root>
|
|
[ "value1", "value2" ] |
<xs:element name="field" type="xs:string" maxOccurs="unbounded"/>※2 |
<field>value1</field> <field>value2</field>※3 |
|
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded">※1 <xs:element name="unnamed_" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> |
<root> <unnamed_1> value1 </unnamed_1> <unnamed_1> value2 </unnamed_1> </root> |
|
|
[ ["value1","value2"], ["value3","value4"] ] |
<xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded">※1 <xs:element name="unnamed_1" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded">※2 <xs:element name="unnamed_2" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> |
<root> <unnamed_1> <unnamed_2> value1 </unnamed_2> <unnamed_2> value2 </unnamed_2> </unnamed_1> <unnamed_1> <unnamed_2> value3 </unnamed_2> <unnamed_2> value4 </unnamed_2> </unnamed_1> </root> |
注 多次元配列および配列で始まるJSON形式データは,アンラップ変換はできません。
注※1 typeは任意タイプを指定できます。
注※2 maxOccursの指定値は2以上の最大配列要素数です。unboundedは無制限の配列要素数を表します。
注※3 ルート要素または多次元配列の場合,変換できません。
- 〈この項の構成〉
(1) ルート要素およびchoice要素の選択
JSON→XML変換では,複数のルート要素の中から最適なルート要素を選択し変換します。また,choice要素内の複数の要素についても,同様に最適な要素を選択し変換します。
|
入力するJSONファイルの定義 |
対応するXSD(XMLスキーマ) |
XML変換結果 |
|---|---|---|
|
123 |
<xs:schema …> <xs:element name="strData" type="xs:string"/> <xs:element name="intData" type="xs:integer"/> </xs:schema> |
<intData>123</intData> |
|
"abcd" |
<strData>abcd</strData> |
要素の選択は,ルート要素またはchoice要素内の要素ごとに,JSON形式データの各要素とのマッチングを行い,マッチ度を計算して,最大のマッチ度を持つXMLスキーマを選択します。最大のマッチ度を持つ要素が複数存在する場合,次の基準で選択します。
-
ルート要素の場合:ルート要素名が文字コード順で最も早い要素を選択します。
-
choice要素内の要素の場合:先に定義された要素を選択します。
最大のマッチ度は,次の表のマッチ度を合計した値となります。
|
条件 |
マッチ度 |
|---|---|
|
対応するattributeのデータ型とJSON value型および突き合わせ条件に合致するattributeの属性値に変換する。 |
4 |
|
対応するelementのデータ型とJSON value型および突き合わせ条件に合致するelementの要素値に変換する。 |
4 |
|
対応するattributeのデータ型とJSON value型に合致するattributeの属性値に変換する。 |
3 |
|
対応するelementのデータ型とJSON value型に合致するelementの要素値に変換する。 |
3 |
|
対応するattributeのデータ型のJSON value型がstringの場合にstring以外のJSON valueをattributeの属性値に変換する。 |
2 |
|
対応するelementのデータ型のJSON value型がstringの場合にstring以外のJSON valueをelementの要素値に変換する。 |
2 |
|
対応するelementが存在しない。 |
0 |
XMLスキーマのデータ型および突き合わせ条件は,「12.3.2(2) データ型の突き合わせ条件」を参照してください。
(2) データ型の突き合わせ条件
JSON→XML変換では,JSON形式データをXMLスキーマの仕様で定義された組み込みデータ型と突き合わせを行い,条件に合うデータ型を選択して変換します。組み込みデータ型以外の派生したデータタイプは,派生元の組み込みデータ型を摘出して突き合わせます。組み込みデータ型を派生して加えたpatternやenumerationなどの制約条件は考慮されないため,不正なJSON形式データが入力された場合,変換結果のXMLデータのバリデーションで制約違反が検出されるおそれがあります。
なお,JSON→XSD変換で生成したXSDファイルは,組み込みデータ型だけを使用するため,このような制約違反は発生しません。
XMLスキーマの組み込みデータ型とJSON形式データの突き合わせ条件を次に示します。
|
組み込みデータ型 |
JSONのデータ型 |
突き合わせ条件 |
|---|---|---|
|
anyURI |
string |
0文字以上の任意の文字列 |
|
base64Binary |
string |
0文字以上のbase64文字列 |
|
boolean |
true, false |
− |
|
date |
string |
dateTimeから時分秒を除く 例:2025-01-01, 2025-01-01Z, 2025-01-01+09:00 |
|
dateTime |
string |
{年}-{月}-{日}T (({時}:{分}:{秒}) | {24時}){タイムゾーン}? 例:2025-01-01T09:00:00Z, 2025-01-01:24:00:00 |
|
decimal |
number |
[+-]?(({数字}+)|({数字}+.{数字}+)|(.{数字}+)) 例:123, 123.456, .456 |
|
integer |
number |
小数点以下を含まないdigit |
|
long |
number |
-9223372036854775808〜9223372036854775807 |
|
int |
number |
-2147483648〜2147483647 |
|
short |
number |
-32768〜32767 |
|
byte |
number |
-128〜127 |
|
nonNegativeInteger |
number |
0以上のinteger |
|
positiveInteger |
number |
1以上のinteger |
|
unsignedLong |
number |
0〜18446744073709551615 |
|
unsignedInt |
number |
0〜4294967295 |
|
unsignedShort |
number |
0〜65535 |
|
unsignedByte |
number |
0〜255 |
|
nonPositiveInteger |
number |
0以下のinteger |
|
negativeInteger |
number |
-1以下のinteger |
|
double |
number |
Double.valueOfで例外が発生しない。 |
|
duration |
string |
Duration.parse()で例外が発生しない。 例:P1Y, P1M1D, P1DT5M |
|
float |
number |
Float.valeOfで例外が発生しない。 |
|
gDay |
string |
---{日}{タイムゾーン}? |
|
gMonth |
string |
--{月}{タイムゾーン}? |
|
gMonthDay |
string |
--{月}-{日}{タイムゾーン}? |
|
gYear |
string |
{年}{タイムゾーン}? |
|
gYearMonth |
string |
{年}-{月}{タイムゾーン}? |
|
hexBinary |
string |
0文字以上の16進文字列 |
|
NOTATION |
string |
XML QName |
|
QName |
string |
XML QName |
|
string |
string |
0文字以上の任意の文字列 |
|
normalizedString |
string |
CR,LF,TABを含まない任意の文字列 |
|
token |
string |
normalizedStringでかつ先頭および末尾にスペースがなく,2文字以上の連続したスペースがない文字列 |
|
language |
string |
[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})* |
|
Name |
string |
XML Name |
|
NCName |
string |
XML NCName |
|
ENTITY |
string |
XML NCName |
|
ID |
string |
XML NCName |
|
IDREF |
string |
XML NCName(対象のIDの存在有無は突き合わせない) |
|
NMTOKEN |
string |
XML Nmtoken |
|
time |
string |
(({時}:{分}:{秒}) | {24時}){タイムゾーン}? |
|
ENTITIES |
string |
スペースで区切られた複数のENTITY |
|
IDREFS |
string |
スペースで区切られた複数のIDREF |
|
NMTOKENS |
string |
スペースで区切られた複数のNMTOKEN |
(凡例)−:該当しない。
注
-
JSONがnullの場合,nillableにtrueが指定されている要素をデータ型に関係なくマッチします。
-
ENTITIE,IDREFS,NMTOKENSなどのlistタイプのデータは,データ変換ではマッピングできません。
(3) simpleTypeとlistの突き合わせ
XMLスキーマのsimpleType要素内のlist要素の構文では,指定したデータ型を持つ値のリスト(スペース区切り)を要素値として定義できます。変換元のJSON形式データが,文字列の場合,変換元文字列をスペース区切りで部分文字列に分割し,分割したすべての部分文字列がitemType属性で指定されたデータ型に合うことを確認します。
ただし,simpleType要素内のlist要素のデータは,データ変換でマッピングできません。
|
入力するJSONファイルの定義 |
対応するXSD(XMLスキーマ) |
XML変換結果 |
|---|---|---|
|
"1 2 3 4 5" |
<xs:schema …> <xs:element name="root"> <xs:simpleType> <xs:list itemType="xs:integer"/> </xs:simpleType> </xs:element> </xs:schema> |
<root>1 2 3 4 5</root> |
|
"1 2 3 4 abc" |
変換されません。 エラーリストに登録されます。 |
(4) サポートするXMLスキーマ要素
JSON→XML変換がサポートするXMLスキーマ要素の組み合わせを次に示します。
|
XMLスキーマ要素 |
親のXMLスキーマ要素 |
子のXMLスキーマ要素 |
|---|---|---|
|
<xs:all> |
<xs:group>, <xs:complexType>, <xs:restriction>, <xs:extension> |
<xs:element> |
|
<xs:attribute> |
<xs:attributeGroup>, <xs:schema>, <xs:complexType>, <xs:restriction>, <xs:extension> |
<xs:simpleType> |
|
<xs:attributeGroup> |
<xs:attributeGroup>, <xs:complexType>, <xs:schema>, <xs:restriction>, <xs:extension> |
<xs:attributeGroup>, <xs:anyAttribute>, <xs:attribute> |
|
<xs:choice> |
<xs:group>, <xs:choice>, <xs:sequence>, <xs:complexType>, <xs:restriction>, <xs:extension> |
<xs:choice>, <xs:sequence>, <xs:element>, <xs:group> |
|
<xs:complexContent> |
<xs:complexType> |
<xs:restriction>, <xs:extension> |
|
<xs:complexType>
|
<xs:element>, <xs:schema>, <xs:redefine>
|
<xs:all>, <xs:choice>, <xs:sequence>, <xs:simpleContent>, <xs:complexContent>, <xs:group>, <xs:attribute>, <xs:attributeGroup>, <xs:anyAttribute> |
|
<xs:element> |
<xs:schema>, <xs:choice>, <xs:all>, <xs:sequence>, <xs:group> |
<xs:complexType>, <xs:simpleType> |
|
<xs:extension> |
<xs:simpleContent>, <xs:complexContent> |
<xs:group>, <xs:sequence>, <xs:choice>, <xs:attribute>, <xs:attributeGroup> |
|
<xs:group> |
<xs:schema>, <xs:choice>, <xs:sequence>, <xs:complexType>, <xs:restriction>, <xs:extension> |
<xs:all>, <xs:choice>, <xs:sequence> |
|
<xs:include> |
<xs:schema> |
なし |
|
<xs:import> |
<xs:schema> |
なし |
|
<xs:list> |
<xs:simpleType> |
<xs:simpleType> |
|
<xs:redefine> |
<xs:schema> |
<xs:simpleType>, <xs:complexType>, <xs:group>, <xs:attributeGroup> |
|
<xs:restriction>※ |
<xs:simpleType>, <xs:simpleContent>, <xs:complexContent> |
<xs:simpleType>, <xs:all>, <xs:choice>, <xs:sequence>, <xs:attribute>, <xs:group>, <xs:attributeGroup>, <xs:anyAttribute> |
|
<xs:schema> |
なし |
<xs:include>, <xs:import>, <xs:redefine>, <xs:simpleType>, <xs:complexType>,<xs:group>, <xs:attributeGroup>, <xs:element>, <xs:attribute> |
|
<xs:sequence> |
<xs:group>, <xs:choice>, <xs:sequence>, <xs:complexType>, <xs:restriction>, <xs:extension> |
<xs:element>, <xs:group>, <xs:choice>, <xs:sequence> |
|
<xs:simpleContent> |
<xs:complexType> |
<xs:restriction>, <xs:extension> |
|
<xs:simpleType> |
<xs:attribute>, <xs:element>, <xs:list>, <xs:restriction>, <xs:schema>, <xs:union> |
<xs:list>, <xs:restriction>, <xs:union> |
|
<xs:union> |
<xs:simpleType> |
<xs:simpleType> |
注 この表に記載がないXMLスキーマ要素は無視されます。
注※ restriction自体はbase属性で指定する元のデータタイプを取得するためにサポートされますが,子要素による制約の追加はサポートされません。
(5) 属性データへの変換
JSON→XML変換では,JSON Objectのフィールド名に一致する要素がなく,属性名に一致する場合は属性データに変換されます。
JSON Objectのフィールド名が<要素名>@<属性名>形式で,要素名に対応する要素に属性名に一致する属性が定義されている場合は,該当する属性の属性値として変換されます。対象要素が配列の場合は,<要素名>@<属性名>配列の対応する配列インデックス要素の属性値として変換されます。JSON Objectのフィールド名が<要素名>@<属性名>でも,対応する要素および属性がXSDファイルに定義されていない場合は変換されません。
JSON→XSD変換で生成したXSDファイルでは属性データは定義されません。属性データへの変換を行う場合は,XSDファイルを編集し,属性データを定義する必要があります。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML]変換結果 |
|---|---|---|
|
{ "data":"value1", "attr1":"value2", "attr2":"value3" } |
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="data" type="xs:string"/> </xs:sequence> <xs:attribute name="attr1" type="xs:string"/> <xs:attribute name="attr2" type="xs:string"/> </xs:complexType> </xs:element> </xs:schema> |
<root attr1="value2" attr2="value3"> <data>value1</data> </root> |
|
{ "field1":"value1", "field1@attr":"a1", "field2":"value2" } |
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field1"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="attr" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="field2" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field1 attr="a1"> value1 </field1> <field2>value2</field2> </root> |
|
{ "field1":[ "value1", "value2", "value3" ], "field1@attr":[ "a1", null, "a3" ], "field2":"value2" }
|
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field1" maxOccurs="unbounded"> <xs:complexType> <xs:simpleContent> <xs:extension base="xs:string"> <xs:attribute name="attr1" type="xs:string"/> </xs:extension> </xs:simpleContent> </xs:complexType> </xs:element> <xs:element name="field2" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field1 attr="a1"> value1 </field1> <field1> value1 </field1> <field1 attr="a3"> value1 </field1> <field2>value2</field2> </root>
|
(6) 配列データの変換(アンラップ変換およびラップ変換)
配列データをアンラップ変換およびラップ変換で変換できます。
アンラップ変換は,配列要素のデータ型が単一の場合にだけ実行できます。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "field":[ "data1", "data2" ] } |
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field" type="xs:string" maxOccurs="unbounded"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field>data1</field> <field>data2</field> </root> |
ラップ変換では,csc:wrapped属性にtrueが設定された要素の子要素(choice要素内のelement要素)から,最適なelement要素を選択し変換します。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "field":[ "data1", "data2" ] }
|
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="item" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field> <item>data1</item> <item>data2</item> </field> </root>
|
(a) ルート要素が配列の場合
JSON形式データのルート要素が配列の場合,アンラップ変換では変換できません。csc:wrapped属性にtrueを設定し,ラップ変換を行う必要があります。配列のルート要素をアンラップ変換した場合は,エラーとなります。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
[ "data1", "data2" ] |
<xs:schema …> <xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="item" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:schema> |
<root> <item>data1</item> <item>data2</item> </root> |
(b) 多次元配列の場合
多次元配列の場合,アンラップ変換では変換できません。csc:wrapped属性にtrueを設定しラップ変換を行う必要があります。多次元配列をアンラップ変換した場合は,エラーとなります。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
[ ["data1","data2"], ["data3","data4"] ]
|
<xs:schema …> <xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="mid" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="item" type="xs:string"/> </xs:choice> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> |
<root> <mid> <item>data1</item> <item>data2</item> </mid> <mid> <item>data3</item> <item>data4</item> </mid> </root>
|
(c) 混合タイプの配列の場合
配列要素に異なるデータタイプを持つ配列は,アンラップ変換できません。csc:wrapped属性にtrueを設定し,ラップ変換を行う必要があります。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
[ "data1", true, { "field1":"data2", "field2":"data3" } ]
|
<xs:schema …> <xs:element name="root" csc:wrapped="true"> <xs:complexType> <xs:choice maxOccurs="unbounded"> <xs:element name="strItem" type="xs:string"/> <xs:element name="boolItem" type="xs:boolean"/> <xs:element name="objItem"> <xs:complexType> <xs:sequence> <xs:element name="field1" type="xs:string"/> <xs:element name="field2" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> |
<root> <strItem>data1</strItem> <boolItem>true</boolItem> <objItem> <field1>data2</field1> <field2>data3</field2> </objItem> </root>
|
(7) 要素の出現順序の維持
要素の出現順序は,JSON Objectのフィールドの出現順に関係なく,XMLスキーマに定義された順序に従ってXMLデータに変換されます。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "givenname":"Taro", "surname":"Yamada", "id":1111 } |
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="surname" type="xs:string"/> <xs:element name="givenname" type="xs:string"/> <xs:element name="id" type="xs:integer"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <surname>Yamada</surname> <givenname>Taro</givenname> <id>1111</id> </root> |
(8) 要素名の別名を使用した変換
XMLスキーマのelement要素のcsc:jsonfield属性にJSONフィールド名を指定すると,JSON ObjectのJSONフィールド名を,XMLスキーマのelement要素のname属性で指定された要素タグを持つXML要素に変換できます。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "<field>":"data" }
|
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element csc:jsonfield="<field>" name="field" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field>data</field> </root>
|
(9) defaultまたはfixedの指定
JSON形式データに対応するフィールドがないelement要素が必須フィールドの場合(minOccurs属性が1以上,またはminOccurs属性の指定がない),defaultまたはfixedの指定があるときはそこで指定された値に変換されます。
defaultまたはfixedを指定した要素の変換は,JSON→XML変換をしたあとXML→JSON変換を行った場合,異なるJSON形式に変換されます。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "name":"dogName" }
|
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="name" type="xs:string"/> <xs:element minOccurs="1" fixed="animal" name="type" type="xs:string"/> <xs:element minOccurs="1" default="dog" name="kind" type="xs:string"/> <xs:element minOccurs="0" default="French bull" name="subkind" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <name>dogName</name> <type>animal</type> <kind>dog</kind> </root>
|
注 subkindは,必須要素ではないため変換されません。
(10) mixed contentの変換
XMLスキーマでmixed contentと指定された要素に対応するフィールドに,「#text」サブフィールドが存在する場合,mixed contentの値となります。
mixed contentのデータは,データ変換でマッピングできません。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "field":"data1", "#text":"data2" }
|
<xs:schema …> <xs:element name="root"> <xs:complexType mixed="true"> <xs:sequence> <xs:element name="field" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field>data1</field> data2 </root>
|
(11) 重複フィールドの変換
JSON Objectに重複したフィールド名が存在する場合,最後に出現したフィールド値だけが有効となります。
|
入力するJSONファイルの定義 |
対応するXMLスキーマ |
XML変換結果 |
|---|---|---|
|
{ "field":"data1", "field":"data2" }
|
<xs:schema …> <xs:element name="root"> <xs:complexType> <xs:sequence> <xs:element name="field" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element> </xs:schema> |
<root> <field>data2</field> </root>
|