您正在查看 Apigee Edge 說明文件。
查看 Apigee X 說明文件。 資訊
優勢
這項政策會將可延伸標記語言 (XML) 格式的訊息轉換為 JavaScript Object Notation (JSON),並且為您提供多個控制訊息轉換方式的選項。
假設意圖是將 XML 格式回應轉換為 JSON 格式的回應,系統會將這項政策附加至回應流程,例如回應 / ProxyEndpoint/PostFlow。
About
在一般中介服務的情況下,傳入要求流程的 JSON 到 XML 政策通常會與傳出回應流程的 XML 至 JSON 政策配對。透過這種方式合併政策,您就能在原生支援 XML 的後端服務中公開 JSON API。
當各種用戶端應用程式 (可能需要 JSON 或 XML) 一起使用 API 時,您可以將回應格式設為 XML 和 XML,並採用 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 格式的回應訊息做為來源,然後建立 JSON 格式的訊息,並在 response
輸出變數中填入。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 Proxy 編輯器中為政策加上標籤。
<DisplayName>Policy Display Name</DisplayName>
預設 |
不適用 如果省略這個元素,系統會使用政策的 |
---|---|
存在必要性 | 選用 |
類型 | 字串 |
<Source> 元素
變數、要求或回應,其中包含您要轉換為 JSON 的 XML 訊息。
來源訊息的 HTTP 內容類型標頭必須設為 application/xml
,否則系統不會強制執行政策。
如未定義 <Source>
,系統會將其視為訊息 (在將政策附加至要求流程時解析要求,或是將政策附加至回應流程的回應)。
如果來源變數無法解析,或解析為非訊息類型,政策會擲回錯誤。
<Source>response</Source>
預設 | 要求或回應 (取決於政策新增至 API Proxy 流程的位置) |
外觀狀態 | 選用 |
類型 | 訊息 |
<OutputVariable> 元素
將 XML 的輸出內容儲存成 JSON 格式轉換。這通常與來源值相同,也就是說,XML 回應通常會轉換成 JSON 回應。
系統會剖析 XML 訊息的酬載並轉換為 JSON,而 XML 格式訊息的 HTTP 內容類型標頭會設為 application/json
。
如未指定 OutputVariable
,系統會將 source
視為 OutputVariable
。舉例來說,如果 source
是 response
,則 OutputVariable
的預設值為 response
。
<OutputVariable>response</OutputVariable>
預設 | 要求或回應 (取決於政策新增至 API Proxy 流程的位置) |
外觀狀態 | 如果 <Source> 元素中定義的變數屬於類型字串,就必須使用這個元素。 |
類型 | 訊息 |
<選項>
選項可讓您控管從 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> 元素
可讓您將空白值轉換為空值。
<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
。只有在 RecognizeNull
為 true 時,這個選項才會生效。
<NullValue>not-present</NullValue>
預設 | null |
外觀狀態 | 選用 |
類型 | 字串 |
<Options>/<命名空間 BlockName>
<Options>/<Default 命名空間 NodeName>
<Options>/<命名空間 Separator> 元素
搭配使用這些元素
<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> ,則必須一併指定其他兩個元素。 |
類型 | 字串 |
<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 到 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 到 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>
有些 XML 酬載 (例如 SOAP) 會有許多父層級,您不想納入已轉換的 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>
在「州」、「城市」、「說明」和「溫度」等級之前,共有 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
,只有一個子項。因此,如果您使用 <StripLevels>3</StripLevels>
(移除前三個層級),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 陣列中。舉例來說,當子項元素的數量可以變動 (從一個到多個),而您想要確保值一律位於陣列中時,這項功能就很實用。這樣做可讓程式碼保持穩定,因為您每次都可以從陣列取得資料。例如:無論陣列中的值數量為何,$.teachers.teacher.studentnames[0]
都會取得陣列中的第一個學生姓名值。
讓我們先回顧一下 XML 到 JSON 的預設行為,然後探索如何使用 <TreatAsArray>/<Path>
控制輸出內容。
如果 XML 文件包含的元素具有多個子項值 (通常是以元素 maxOccurs='unbounded'
的結構定義為依據),XML 對 JSON 政策會自動將這些值放入陣列中。舉例來說,下列 XML 區塊
<teacher> <name>teacherA</name> <studentnames> <name>student1</name> <name>student2</name> </studentnames> </teacher>
...會自動轉換為下列 JSON,無須特殊政策設定:
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : [ "student1", "student2" ]} } } }
此時,系統會將兩個學生姓名置於陣列中。
不過,如果 XML 文件中只有一位學生,則 XML 到 JSON 政策會自動將該值視為單一字串,而非字串陣列,如以下範例所示:
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : "student1" } } } }
在先前的範例中,類似的資料是以陣列的形式呈現,其中一個則是以單一字串的形式轉換。您可以在 <TreatAsArray>/<Path>
元素中控制輸出內容。舉例來說,您可以確保學生姓名一律存放在陣列中 (即使只有一個值)。進行這項設定時,須找出要放入陣列中的值的元素路徑,如下所示:
<Options> <TreatAsArray> <Path>teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
上述設定會編寫如下所示的 JSON:
{ "teachers" : { "teacher" : { "name" : "teacherA", "studentnames" : { "name" : ["student1"] } ] } } }
請注意,學生 1 位於陣列中。現在,無論您有一或多位學生,都可以使用以下 JSONPath,從程式碼中的 JSON 陣列擷取學生:$.teachers.teacher.studentnames.name[0]
<Path>
元素也具有 unwrap
屬性,詳情請參閱下一節。
預設 | NA |
外觀狀態 | 選用 |
類型 | 字串 |
屬性
<Options> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
屬性 | 說明 | 存在必要性 | 類型 |
---|---|---|---|
解除包裝 |
預設值:false 從 JSON 輸出中移除元素。使用這個函式來簡化或整併 JSON (「解除包裝」),這樣也會縮短擷取值所需的 JSONPath。例如,您可以整併 JSON 並使用 以下為 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。
<格式>
格式可讓你控管從 XML 轉換成 JSON 格式的轉換。輸入預先定義的範本名稱,其中包含本主題所述的特定選項元素組合。預先定義的格式包括: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> 元素的變數類型無效,就會發生這個錯誤。有效的變數類型為訊息和字串。 |
build |
steps.xmltojson.OutputVariableIsNotAvailable |
500 | 如果 XML 至 JSON 政策的 <Source> 元素中指定的變數為類型字串,且 <OutputVariable> 元素未定義,就會發生這個錯誤。如果 <Source> 元素中定義的變數為類型字串,則 <OutputVariable> 元素為必要元素。 |
build |
steps.xmltojson.SourceUnavailable |
500 |
如果在將 XML 至 JSON 政策的 <Source> 元素中,指定 message 變數,就會發生這個錯誤:
|
build |
部署錯誤
若您部署包含這項政策的 Proxy,就可能會發生這些錯誤。
錯誤名稱 | 原因 | 修正 |
---|---|---|
EitherOptionOrFormat |
如果未在 XML 中對 JSON 政策宣告 <Options> 或 <Format> 的其中一個元素,API Proxy 的部署作業就會失敗。 |
build |
UnknownFormat |
如果 XML 到 JSON 政策中的 <Format> 元素定義了不明格式,API Proxy 部署就會失敗。預先定義的格式包括:xml.com 、yahoo 、google 和 badgerFish 。 |
build |
錯誤變數
這些變數是在執行階段錯誤發生時設定。詳情請參閱「政策錯誤的注意事項」。
錯誤回應範例
{ "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 到 XML:從 JSON 到 XML 政策