您目前查看的是 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>| 屬性 | 說明 | 存在必要性 | 類型 |
|---|---|---|---|
| 解除包裝 |
預設值: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 轉 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>,則為必要屬性。 |
| 類型 | 字串 |
結構定義
錯誤參考資料
本節說明在這項政策觸發錯誤時,所傳回的錯誤代碼和錯誤訊息,以及 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 的 <Source> 元素中指定的變數為
JSON 政策的類型為字串,且未定義 <OutputVariable> 元素。
如果在 <Source> 中定義的變數,則 <OutputVariable> 是必要元素
元素屬於類型字串。 |
build |
steps.xmltojson.SourceUnavailable |
500 |
如果系統傳回這個錯誤,表示 message
而 XML 到 JSON 政策的 <Source> 元素中指定的是以下任一變數:
|
build |
部署錯誤
當您部署含有這項政策的 Proxy 時,可能會發生這些錯誤。
| 錯誤名稱 | 原因 | 修正 |
|---|---|---|
EitherOptionOrFormat |
如果不是 <Options> 或 <Format> 元素
在 XML 政策中宣告為 JSON 政策,則 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 政策