概要
このポリシーは、メッセージを拡張マークアップ言語(XML)形式から JavaScript Object Notation(JSON)に変換します。これにより、メッセージの変換方法を制御するための選択肢が多彩になります。
XML 形式のレスポンスを JSON 形式のレスポンスに変換することが目的であると仮定した場合、このポリシーはレスポンス フロー(たとえば Response / ProxyEndpoint / PostFlow)に接続されます。
説明
代表的な仲介シナリオでは、多くの場合、受信リクエスト フローでの JSON to XML ポリシーを送信レスポンス フローでの XML to JSON ポリシーとペアで使用されます。ポリシーをこのように結び付けることで、XML のみをネイティブ サポートするバックエンド サービスに対して JSON API を公開できます。
API が、JSON あるいは XML を必要とする可能性のある多様なクライアント アプリで消費されるシナリオでは、JSON to XML ポリシーと XML to JSON ポリシーを条件に応じて実行するよう構成することで、レスポンス形式を動的に設定できます。このシナリオの実装については、フロー変数と条件をご覧ください。
サンプル
JSON と XML の間の変換について詳しくは、http://community.apigee.com/articles/1839/converting-between-xml-and-json-what-you-need-to-k.html をご覧ください。
レスポンスを変換する
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
この構成(XML を JSON に変換するために必要な最小限の構成)は、XML 形式のレスポンス メッセージをソースとして受け取り、出力変数 response
に入力される JSON 形式のメッセージを作成します。Edge はこの変数の内容を、自動的に次の処理ステップのメッセージとして使用します。
要素リファレンス
このポリシーで構成できる要素と属性は、以下のとおりです。
<XMLToJSON async="false" continueOnError="false" enabled="true" name="XML-to-JSON-1"> <DisplayName>XML to JSON 1</DisplayName> <Source>response</Source> <OutputVariable>response</OutputVariable> <Options> <RecognizeNumber>true</RecognizeNumber> <RecognizeBoolean>true</RecognizeBoolean> <RecognizeNull>true</RecognizeNull> <NullValue>NULL</NullValue> <NamespaceBlockName>#namespaces</NamespaceBlockName> <DefaultNamespaceNodeName>&</DefaultNamespaceNodeName> <NamespaceSeparator>***</NamespaceSeparator> <TextAlwaysAsProperty>true</TextAlwaysAsProperty> <TextNodeName>TEXT</TextNodeName> <AttributeBlockName>FOO_BLOCK</AttributeBlockName> <AttributePrefix>BAR_</AttributePrefix> <OutputPrefix>PREFIX_</OutputPrefix> <OutputSuffix>_SUFFIX</OutputSuffix> <StripLevels>2</StripLevels> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options> <!-- Use Options or Format, not both --> <Format>yahoo</Format> </XMLToJSON>
<XMLtoJSON> 属性
<XMLtoJSON async="false" continueOnError="false" enabled="true" name="XML-to-JSON-1">
次の表に、すべてのポリシーの親要素に共通する属性を示します。
属性 | 説明 | デフォルト | 要否 |
---|---|---|---|
name |
ポリシーの内部名。 管理 UI プロキシ エディタで |
なし | 必須 |
continueOnError |
ポリシーが失敗した場合にエラーを返すには、 ポリシーが失敗した後もフローの実行を続行する場合は、 |
false | 省略可 |
enabled |
ポリシーを適用するには、 ポリシーを無効にするには、 |
true | 省略可 |
async |
この属性は非推奨となりました。 |
false | 非推奨 |
<DisplayName> 要素
管理 UI プロキシ エディタで name
属性と一緒に使用して、ポリシーのラベルに使用する自然言語名を指定します。
<DisplayName>Policy Display Name</DisplayName>
デフォルト |
なし この要素を省略した場合、ポリシーの |
---|---|
要否 | 省略可 |
タイプ | 文字列 |
<Source> 要素
JSON に変換する XML メッセージを含む変数、リクエスト、またはレスポンスです。
ソース メッセージの HTTP Content-type ヘッダーを application/xml
に設定する必要があります。設定されていない場合、ポリシーは適用されません。
<Source>
が定義されていない場合は、メッセージとして処理されます(ポリシーがリクエスト フローに接続されている場合はリクエスト、ポリシーがレスポンス フローに接続されている場合はレスポンスに解決される)。
ソース変数を解決できない場合、あるいはメッセージ以外のタイプに解決される場合、ポリシーはエラーを返します。
<Source>response</Source>
デフォルト | リクエストまたはレスポンス(ポリシーが API プロキシフローに追加されている場所によって決まる)。 |
要否 | 省略可 |
型 | メッセージ |
<OutputVariable> 要素
XML to JSON 形式変換の出力を格納します。これは通常はソースと同じ値です。つまり、通常は XML レスポンスが JSON レスポンスに変換されます。
XML メッセージのペイロードが解析されて JSON に変換され、XML 形式のメッセージの HTTP Content-type ヘッダーは application/json
に設定されます。
OutputVariable
が指定されていない場合、source
は OutputVariable
として扱われます。たとえば、source
が response
である場合、OutputVariable
のデフォルトは response
になります。
<OutputVariable>response</OutputVariable>
デフォルト | リクエストまたはレスポンス(ポリシーが API プロキシフローに追加されている場所によって決まる)。 |
要否 | <Source> 要素で定義された変数が文字列型の場合、この要素は必須です。 |
型 | メッセージ |
<Options>
Options により、XML から JSON への変換を制御できます。特定の変換設定を追加できる <Options>
グループ、または事前定義オプションのテンプレートを参照できる <Format>
要素を使用します。<Options>
と <Format>
の両方を使用することはできません。
<Format>
を使用しない場合は <Options>
が必要です。
<Options>/<RecognizeNumber> 要素
true の場合、XML ペイロードの数値フィールドは元の形式を維持します。
<RecognizeNumber>true</RecognizeNumber>
以下の XML の例を考えてみましょう。
<a> <b>100</b> <c>value</c> </a>
true
の場合、次のように変換されます。
{ "a": { "b": 100, "c": "value" } }
false
の場合、次のように変換されます。
{ "a": { "b": "100", "c": "value" } }
デフォルト | false |
要否 | 省略可 |
型 | ブール値 |
<Options>/<RecognizeBoolean> 要素
変換の際に true/false ブール値が維持され、文字列に変換されません。
<RecognizeBoolean>true</RecognizeBoolean>
次の XML 例の場合、以下のように変換されます。
<a> <b>true</b> <c>value</c> </a>
true
の場合、次のように変換されます。
{ "a": { "b": true, "c": "value" } }
false
の場合、次のように変換されます。
{ "a": { "b": "true", "c": "value" } }
デフォルト | false |
要否 | 省略可 |
型 | ブール値 |
<Options>/<RecognizeNull> 要素
空の値を null 値に変換できます。
<RecognizeNull>true</RecognizeNull>
次の XML の場合、以下のように変換されます。
<a> <b></b> <c>value</c> </a>
true
の場合、次のように変換されます。
{ "a": { "b": null, "c": "value" } }
false
の場合、次のように変換されます。
{ "a": { "b": {}, "c": "value" } }
デフォルト | false |
要否 | 省略可 |
型 | ブール値 |
<Options>/<NullValue> 要素
変換されるメッセージ内の null 値を構成するものを示します。デフォルトでは、値は NULL
です。
<NullValue>NULL</NullValue>
デフォルト | NULL |
要否 | 省略可 |
型 | 文字列 |
<Options>/<NamespaceBlockName> 要素
<Options>/<DefaultNamespaceNodeName> 要素
<Options>/<NamespaceSeparator> 要素
これらの要素を一緒に使用します。
<NamespaceBlockName>#namespaces</NamespaceBlockName> <DefaultNamespaceNodeName>&</DefaultNamespaceNodeName> <NamespaceSeparator>***</NamespaceSeparator>
以下の XML の例を考えてみましょう。
<a xmlns="http://ns.com" xmlns:ns1="http://ns1.com"> <ns1:b>value</ns1:b> </a>
NamespaceSeparator
が指定されていない場合、次の JSON 構造が生成されます。
{ "a": { "b": "value" } }
NamespaceBlockName
要素、DefaultNamespaceNodeName
要素、NamespaceSeparator
要素がそれぞれ #namespaces
、&
、***
として指定されている場合、次の JSON 構造が生成されます。
{ "a": { "#namespaces": { "&": "http://ns.com", "ns1": "http://ns1.com" }, "ns1***b": "value" } }
デフォルト | 上の例をご覧ください。 |
要否 | 省略可 ただし、 <NamespaceBlockName> を指定する場合は、その他の 2 つの要素も指定する必要があります。 |
型 | 文字列 |
<Options>/<TextAlwaysAsProperty> 要素
<Options>/<TextNodeName> 要素
これらの要素を一緒に使用します。
true
に設定すると、XML 要素のコンテンツが文字列プロパティに変換されます。
<TextAlwaysAsProperty>true</TextAlwaysAsProperty> <TextNodeName>TEXT</TextNodeName>
次の XML の場合、以下のように変換されます。
<a> <b>value1</b> <c>value2<d>value3</d>value4</c> </a>
TextAlwaysAsProperty
が true
に設定され、TextNodeName
が TEXT
として指定されている場合、次の JSON 構造が生成されます。
{ "a": { "b": { "TEXT": "value1" }, "c": { "TEXT": [ "value2", "value4" ], "d": { "TEXT": "value3" } } } }
TextAlwaysAsProperty
が false
に設定され、TextNodeName
が TEXT
として指定されている場合、次の JSON 構造が生成されます。
{ "a": { "b": "value1", "c": { "TEXT": [ "value2", "value4" ], { "d": "value3", } } }
デフォルト | <TextAlwaysAsProperty> : false <TextNodeName> : 該当なし |
要否 | 省略可 |
型 | <TextAlwaysAsProperty> : ブール値<TextNodeName> : 文字列 |
<Options>/<AttributeBlockName> 要素
<Options>/<AttributePrefix> 要素
これらの要素を一緒に使用します。
値を JSON ブロックにグループ化して、属性名に接頭辞を追加できます。
<AttributeBlockName>FOO_BLOCK</AttributeBlockName> <AttributePrefix>BAR_</AttributePrefix>
以下の XML の例を考えてみましょう。
<a attrib1="value1" attrib2="value2"/>
XML to JSON の例で定義されているように、両方の属性(AttributeBlockName
と AttributePrefix
)が指定されている場合、次の JSON 構造が生成されます。
{ "a": { "FOO_BLOCK": { "BAR_attrib1": "value1", "BAR_attrib2": "value2" } } }
AttributeBlockName
のみを指定すると、次の JSON 構造が生成されます。
{ "a": { "FOO_BLOCK": { "attrib1": "value1", "attrib2": "value2" } } }
AttributePrefix
のみを指定すると、次の JSON 構造が生成されます。
{ "a": { "BAR_attrib1": "value1", "BAR_attrib2": "value2" } }
どちらも指定されていない場合、次の JSON 構造が生成されます。
{ "a": { "attrib1": "value1", "attrib2": "value2" } }
デフォルト | 上の例をご覧ください。 |
要否 | 省略可 |
型 | 文字列 |
<Options>/<OutputPrefix> 要素
<Options>/<OutputSuffix> 要素
これらの要素を一緒に使用します。
<OutputPrefix>PREFIX_</OutputPrefix> <OutputSuffix>_SUFFIX</OutputSuffix>
以下の XML の例を考えてみましょう。
<a>value</a>
XML to JSON の例で定義されているように、両方の属性(OutputPrefix
と OutputSuffix
)が指定されている場合、次の JSON 構造が生成されます。
PREFIX_{ "a": "value" }_SUFFIX
OutputPrefix
のみを指定すると、次の JSON 構造が生成されます。
PREFIX_{ "a" : "value" }
OutputSuffix
のみを指定すると、次の JSON 構造が生成されます。
{ "a" : "value" }_SUFFIX
OutputPrefix
と OutputSuffix
のいずれも指定されていない場合、次の JSON 構造が生成されます。
{ "a": "value" }
デフォルト | 上の例をご覧ください。 |
要否 | 省略可 |
型 | 文字列 |
<Options>/<StripLevels> 要素
<Options> <StripLevels>4</StripLevels> </Options>
SOAP などの XML ペイロードには、変換後の JSON に含めたくない親レベルが多数あることがあります。以下の例では、SOAP レスポンスに多数のレベルが含まれています。
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/Schemata-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <soap:Body> <GetCityWeatherByZIPResponse xmlns="http://ws.cdyne.com/WeatherWS/"> <GetCityWeatherByZIPResult> <State>CO</State> <City>Denver</City> <Description>Sunny</Description> <Temperature>62</Temperature> </GetCityWeatherByZIPResult> </GetCityWeatherByZIPResponse> </soap:Body> </soap:Envelope>
State、City、Description、および Temperature レベルに達するまでに 4 つのレベルがあります。<StripLevels>
を使用しない場合、変換した後の JSON レスポンスは次のようになります。
{ "Envelope" : { "Body" : { "GetCityWeatherByZIPResponse" : { "GetCityWeatherByZIPResult" : { "State" : "CO", "City" : "Denver", "Description" : "Sunny", "Temperature" : "62" } } } } }
JSON レスポンスの最初の 4 つのレベルを削除する場合は、<StripLevels>4</StripLevels>
を設定します。これにより、次の JSON が生成されます。
{ "State" : "CO", "City" : "Denver", "Description" : "Sunny", "Temperature" : "62" }
除去できるレベルは、複数の子を含んでいる最初の要素までです。これが意味するところについては、より複雑な JSON の例を見てみましょう。
{ "Envelope" : { "Body" : { "GetCityForecastByZIPResponse" : { "GetCityForecastByZIPResult" : { "ResponseText" : "City Found", "ForecastResult" : { "Forecast" : [ { "ProbabilityOfPrecipiation" : { "Nighttime" : "00", "Daytime" : 10 } ...
この例のレベル 3 は GetCityForecastByZIPResponse
です。子要素は 1 つだけです。したがって、<StripLevels>3</StripLevels>
を使用する(最初の 3 つのレベルを削除する)場合、JSON は次のようになります。
{ "GetCityForecastByZIPResult" : { "ResponseText" : "City Found", "ForecastResult" : { "Forecast" : [ { "ProbabilityOfPrecipiation" : { "Nighttime" : "00", "Daytime" : 10 } ...
GetCityForecastByZIPResult
には複数の子要素があります。これが複数の子要素を持つ最初の要素であるため、この最後のレベルを <StripLevels>4</StripLevels>
を使用して削除できます。これにより、次の JSON が得られます。
{ "ResponseText" : "City Found", "ForecastResult" : { "Forecast" : [ { "ProbabilityOfPrecipiation" : { "Nighttime" : "00", "Daytime" : 10 } ...
レベル 4 が複数の子を含んだ最初のレベルであるため、これより下のレベルは除去できません。除去レベルを 5、6、7 といった具合に設定しても、引き続き上記のレスポンスが取得されます。
デフォルト | 0 (レベル除去なし) |
要否 | 省略可 |
型 | 整数 |
<Options>/<TreatAsArray>/<Path> 要素
<Options> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
これらの要素の組み合わせにより、XML ドキュメントの値を確実に JSON 配列に入れることができます。これは、たとえば子要素の数が(1 から複数まで)異なる可能性があり、値が常に配列内に入るようにする場合に役立ちます。こうすることで、配列からデータを毎回同じように取得できるため、コードを安定させることができます。たとえば、$.teachers.teacher.studentnames[0]
は配列内の値の数に関係なく、配列内の最初の生徒名の値を取得します。
XML to JSON のデフォルトの動作を確認し、<TreatAsArray>/<Path>
を使用して出力を制御する方法を見てみましょう。
XML ドキュメントに複数の子の値を持つ要素が含まれている場合(通常は要素の maxOccurs='unbounded'
のスキーマに基づきます)、XML to JSON ポリシーは自動的に配列に格納します。たとえば、次の XML ブロックを見てみましょう。
<teacher> <name>teacherA</name> <studentnames> <name>student1</name> <name>student2</name> </studentnames> </teacher>
これは、特殊なポリシー構成なしで、以下の JSON に自動的に変換されます。
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : [ "student1", "student2" ]} } } }
2 つの生徒名が配列に入っています。
ただし、1 つの生徒しか XML ドキュメントに存在しない場合、XML to JSON ポリシーは自動的にこの値を、文字列の配列でなく、ひとつの文字列として扱います。これを、下の例で示します。
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : "student1" } } } }
これまでの例では、同様のデータが、あるものは配列に、またあるものはひとつの文字列にと、さまざまな方法で変換されていました。ここで、<TreatAsArray>/<Path>
要素を使用して出力を制御できます。たとえば、生徒名の値が 1 つしかなくても、常に配列に入れられるようにできます。このように構成するには、配列に入れたい値を持つ要素へのパスを、以下のようにして見つけます。
<Options> <TreatAsArray> <Path>teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
上の構成によって、次のような JSON が作成されます。
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : ["student1"] } ] } } }
student1 が配列の中に入るようになりました。これで、生徒が 1 人か複数かにかかわらず、次の JSONPath を使用してコード内の JSON 配列から取得できます。
$.teachers.teacher.studentnames.name[0]
<Path>
要素にも unwrap
属性があります。これについては次のセクションで説明します。
デフォルト | なし |
要否 | 省略可 |
型 | 文字列 |
属性
<Options> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
属性 | 説明 | 要否 | 型 |
---|---|---|---|
unwrap |
デフォルト: false JSON 出力から要素を削除します。これを使用することで、JSON を合理化、つまりフラット(「ラップ解除」)にします。値を取得するために必要な JSONPath も短くなります。たとえば、 以下に JSON の例を示します。 { "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : [ "student1", "student2" ]}... この例では、 <TreatAsArray> <Path unwrap="true">teachers/teacher</Path> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray>
{ "teachers" : [{ "name" : "teacherA", "studentnames" : ["student1","student2"] }]...
|
省略可 | ブール値 |
その他の例と機能のチュートリアルについては、次の Apigee コミュニティの記事をご覧ください: https://community.apigee.com/content/kbentry/33374/new-edge-minifeature-the-treatasarray-option-in-th.html。
<Format>
Format により、XML から JSON への変換を制御できるようになります。このトピックで説明した特定の Options 要素の組み合わせが含まれている、事前定義テンプレートの名前を入力します。事前定義された形式には次のものがあります。xml.com
、yahoo
、google
、badgerFish
。
<Format>
要素か <Options>
グループのいずれかを使用します。<Format>
と <Options>
の両方は使用できません。
以下は、それぞれの事前定義テンプレートの形式定義です。
xml.com
<RecognizeNull>true</RecognizeNull> <TextNodeName>#text</TextNodeName> <AttributePrefix>@</AttributePrefix>
yahoo
<RecognizeNumber>true</RecognizeNumber> <TextNodeName>content</TextNodeName>
<TextNodeName>$t</TextNodeName> <NamespaceSeparator>$</NamespaceSeparator> <TextAlwaysAsProperty>true</TextAlwaysAsProperty>
badgerFish
<TextNodeName>$</TextNodeName> <TextAlwaysAsProperty>true</TextAlwaysAsProperty> <AttributePrefix>@</AttributePrefix> <NamespaceSeparator>:</NamespaceSeparator> <NamespaceBlockName>@xmlns</NamespaceBlockName> <DefaultNamespaceNodeName>$</DefaultNamespaceNodeName>
要素の構文:
<Format>yahoo</Format>
デフォルト | 使用可能な形式の名前を入力します。xml.com 、yahoo 、google 、badgerFish |
要否 | <Options> を使用しない場合は必須です。 |
型 | 文字列 |
スキーマ
エラー リファレンス
このセクションでは、このポリシーによってエラーがトリガーされたときに返される障害コードとエラー メッセージ、Edge によって設定される障害変数について説明します。 これは、障害に対処する障害ルールを作成するうえで重要な情報です。詳細については、ポリシーエラーについて知っておくべきことと障害の処理をご覧ください。
ランタイム エラー
このエラーは、ポリシーの実行時に発生することがあります。
障害コード | HTTP ステータス | 原因 | 修正 |
---|---|---|---|
steps.xmltojson.ExecutionFailed |
500 | このエラーは、入力ペイロード(XML)が空、入力 XML が無効、または形式が正しくない場合に発生します。 | build |
steps.xmltojson.InCompatibleType |
500 | このエラーは、<Source> 要素で定義された変数の型と、<OutputVariable> 要素で定義された変数の型が異なる場合に発生します。<Source> 要素に含まれる変数の型と、<OutputVariable> 要素に含まれる変数の型は一致する必要があります。 |
build |
steps.xmltojson.InvalidSourceType |
500 | このエラーは、<Source> 要素の定義に使用される変数の型が無効な場合に発生します。有効な変数の型は、message と String です。 |
build |
steps.xmltojson.OutputVariableIsNotAvailable |
500 | このエラーは、XML to JSON ポリシーの <Source> 要素で指定された変数が String 型であり、<OutputVariable> 要素が定義されていない場合に発生します。<Source> 要素で定義された変数が String 型の場合、<OutputVariable> 要素は必須です。 |
build |
steps.xmltojson.SourceUnavailable |
500 | このエラーは、XML to JSON ポリシーの <Source> 要素で指定された message 変数が、次のいずれかである場合に発生します。
|
build |
デプロイエラー
以下のエラーは、このポリシーを含むプロキシをデプロイするときに発生することがあります。
エラー名 | 原因 | 修正 |
---|---|---|
EitherOptionOrFormat |
<Options> または <Format> のいずれかの要素が XML to JSON ポリシーに宣言されていない場合、API プロキシのデプロイは失敗します。 |
build |
UnknownFormat |
XML to JSON ポリシー内の <Format> 要素に不明な形式が定義されている場合、API プロキシのデプロイは失敗します。事前定義された形式には、xml.com 、yahoo 、google 、badgerFish があります。 |
build |
障害変数
ランタイム エラーが発生すると、次の変数が設定されます。詳細については、ポリシーエラーについて知っておくべきことをご覧ください。
変数 | 説明 | 例 |
---|---|---|
fault.name="fault_name" |
fault_name は、上記のランタイム エラーの表に記載されている障害の名前です。障害名は、障害コードの最後の部分です。 | fault.name = "SourceUnavailable" |
xmltojson.policy_name.failed |
policy_name は、障害が発生したポリシーのユーザー指定の名前です。 | xmltojson.XMLtoJSON-1.failed = true |
エラー レスポンスの例
{ "fault": { "faultstring": "XMLToJSON[XMLtoJSON-1]: Source xyz is not available", "detail": { "errorcode": "steps.xml2json.SourceUnavailable" } } }
障害ルールの例
<faultrule name="VariableOfNonMsgType"></faultrule><FaultRule name="XML to JSON Faults"> <Step> <Name>AM-SourceUnavailableMessage</Name> <Condition>(fault.name Matches "SourceUnavailable") </Condition> </Step> <Step> <Name>AM-BadXML</Name> <Condition>(fault.name = "ExecutionFailed")</Condition> </Step> <Condition>(xmltojson.XMLtoJSON-1.failed = true) </Condition> </FaultRule>
関連トピック
JSON to XML: JSON to XML ポリシー