
概要
このポリシーは、メッセージを拡張マークアップ言語(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 |
ポリシーの内部名。 必要に応じて |
なし | 必須 |
continueOnError |
ポリシーが失敗した場合にエラーを返すには、 ポリシーが失敗してもフローの実行を続けるには |
false | 省略可 |
enabled |
ポリシーを適用するには、 ポリシーを無効にするには、 |
true | 省略可 |
async |
この属性はサポートが終了しています。 |
false | 非推奨 |
<DisplayName> 要素
name
属性に加えて、管理 UI プロキシ エディタでポリシーを別の自然言語名でラベル付けするために使います。
<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> を使用しない場合は必須です。 |
型 | 文字列 |
スキーマ
エラー リファレンス
This section describes the fault codes and error messages that are returned and fault variables that are set by Edge when this policy triggers an error. This information is important to know if you are developing fault rules to handle faults. To learn more, see What you need to know about policy errors and Handling faults.
Runtime errors
These errors can occur when the policy executes.
Fault code | HTTP status | Cause | Fix |
---|---|---|---|
steps.xmltojson.ExecutionFailed |
500 | This error occurs when the input payload (XML) is empty or the input XML is invalid or malformed. | build |
steps.xmltojson.InCompatibleType |
500 | This error occurs if the type of the variable defined in the <Source> element and the
<OutputVariable> element are not the same. It is mandatory that the type of the variables
contained within the <Source> element and the <OutputVariable> element matches.
|
build |
steps.xmltojson.InvalidSourceType |
500 | This error occurs if the type of the variable used to define the <Source> element is
invalid.The valid types of variable are message and string. |
build |
steps.xmltojson.OutputVariableIsNotAvailable |
500 | This error occurs if the variable specified in the <Source> element of the XML to
JSON policy is of type string and the <OutputVariable> element is not defined.
The <OutputVariable> element is mandatory when the variable defined in the <Source>
element is of type string. |
build |
steps.xmltojson.SourceUnavailable |
500 |
This error occurs if the message
variable specified in the <Source> element of the XML to JSON policy is either:
|
build |
Deployment errors
These errors can occur when you deploy a proxy containing this policy.
Error name | Cause | Fix |
---|---|---|
EitherOptionOrFormat |
If one of the elements <Options> or <Format> is not
declared in the XML to JSON Policy, then the deployment of the API proxy fails.
|
build |
UnknownFormat |
If the <Format> element within the XML to JSON policy has an unknown
format defined, then the deployment of the API proxy fails. Predefined formats include:
xml.com , yahoo , google , and badgerFish .
|
build |
Fault variables
These variables are set when a runtime error occurs. For more information, see What you need to know about policy errors.
Variables | Where | Example |
---|---|---|
fault.name="fault_name" |
fault_name is the name of the fault, as listed in the Runtime errors table above. The fault name is the last part of the fault code. | fault.name = "SourceUnavailable" |
xmltojson.policy_name.failed |
policy_name is the user-specified name of the policy that threw the fault. | xmltojson.XMLtoJSON-1.failed = true |
Example error response
{ "fault": { "faultstring": "XMLToJSON[XMLtoJSON-1]: Source xyz is not available", "detail": { "errorcode": "steps.xml2json.SourceUnavailable" } } }
Example fault rule
<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 ポリシー