您目前查看的是 Apigee Edge 說明文件。
前往 Apigee X 說明文件。 info
結果
這項政策會將訊息從可延伸標記語言 (XML) 格式轉換為 JavaScript 物件標記法 (JSON),並提供多種選項,讓您控管訊息的轉換方式。
假設目的是將 XML 格式的回應轉換為 JSON 格式的回應,則政策會附加至回應流程 (例如 Response / ProxyEndpoint / PostFlow)。
關於
在典型的中介服務情境中,傳入要求流程的 JSON 轉 XML 政策,通常會與傳出回應流程的 XML 轉 JSON 政策配對。以這種方式合併政策後,即可為僅原生支援 XML 的後端服務公開 JSON API。
如果 API 用於各種用戶端應用程式,且可能需要 JSON 或 XML,您可以設定 JSON 轉 XML 和 XML 轉 JSON 政策,有條件地執行,動態設定回應格式。如要瞭解如何實作這個情境,請參閱「流程變數和條件」。
範例
如要詳細瞭解如何在 JSON 和 XML 之間轉換,請參閱「使用 Apigee 在 XML 和 JSON 之間轉換:須知事項」。
轉換回覆
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
這項設定是將 XML 轉換為 JSON 時所需的最低設定,會將 XML 格式的回覆訊息做為來源,然後建立 JSON 格式的訊息,並填入 response OutputVariable。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 Content-type 標頭必須設為 application/xml,否則系統不會強制執行這項政策。
如果未定義 <Source>,則會視為訊息 (當政策附加至要求流程時,會解析為要求;當政策附加至回應流程時,會解析為回應)。
如果無法解析來源變數,或解析為非訊息類型,政策就會擲回錯誤。
<Source>response</Source>
| 預設 | 要求或回應,取決於政策在 API Proxy 流程中的新增位置 |
| 外觀狀態 | 選用 |
| 類型 | 訊息 |
<OutputVariable> 元素
儲存 XML 轉 JSON 格式的輸出內容。這通常與來源的值相同,也就是 XML 回應通常會轉換為 JSON 回應。
系統會剖析 XML 訊息的酬載並轉換為 JSON,且 XML 格式訊息的 HTTP Content-type 標頭會設為 application/json。
如未指定 OutputVariable,系統會將 source 視為 OutputVariable。舉例來說,如果 source 是 response,則 OutputVariable 預設為 response。
<OutputVariable>response</OutputVariable>
| 預設 | 要求或回應,取決於政策在 API Proxy 流程中的新增位置 |
| 外觀狀態 | 如果 <Source> 元素中定義的變數屬於字串類型,就必須使用這個元素。 |
| 類型 | 訊息 |
<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> 元素
可將空白值轉換為空值。
<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>/<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>,也必須指定其他兩個元素。 |
| 類型 | 字串 |
<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"/>
如果兩個屬性 (AttributeBlockName 和 AttributePrefix) 都指定為 XML 至 JSON 範例中定義的屬性,系統會產生下列 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>
如果兩個屬性 (OutputPrefix 和 OutputSuffix) 都指定為 XML 至 JSON 範例中定義的屬性,系統會產生下列 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"]
}
]
}
}
}請注意,student1 現在位於陣列中。現在,無論學生人數多寡,您都可以使用下列 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 扁平化,並使用 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 社群文章:社群教學課程:XML to JSON 政策中的 TreatAsArray 選項。
<Format>
格式可讓您控管 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>,則為必要屬性。 |
| 類型 | 字串 |
結構定義
錯誤參考資料
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 轉 XML:JSON 轉 XML 政策