本页面适用于 Apigee 和 Apigee Hybrid。
查看 Apigee Edge 文档。
内容
此政策用于将消息从可扩展标记语言 (XML) 格式转换为 JavaScript 对象表示法 (JSON),并为您提供若干选项来控制消息的转换方式。
假设意图将 XML 格式的响应转换为 JSON 格式的响应,则政策将附加到响应流(例如,Response / ProxyEndpoint/PostFlow)。
此政策为标准政策,可部署到任何环境类型。如需了解政策类型以及在每种环境类型中的可用性,请参阅政策类型。
关于
在典型的中介情景中,入站请求流中的 JSON 到 XML 政策通常与出站响应流上的 XML 到 JSON 政策配对。通过以这种方式组合政策,您可以为本地仅支持 XML 的后端服务公开 JSON API。
如果 API 由不同的客户端应用使用,该客户端应用可能需要 JSON 或 XML 格式,则可以通过将 JSON 配置为 XML 以及将 XML 配置为 JSON 的政策来动态设置响应格式,以便有条件地执行。如需了解此使用场景的实现情况,请参阅流变量和条件。
示例
有关在 JSON 和 XML 之间进行转换的详细讨论,请参阅本文。
转换响应
<XMLToJSON name="ConvertToJSON"> <Options> </Options> <OutputVariable>response</OutputVariable> <Source>response</Source> </XMLToJSON>
此配置(将 XML 转换为 JSON 所需的最少配置)将 XML 格式的响应消息作为源,然后创建在 response
OutputVariable 中填充的 JSON 格式消息。Apigee 会自动将此变量的内容用作下一个处理步骤的消息。
元素参考
下面是您可以在此政策中配置的元素和属性。
<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">
下表介绍了所有政策父元素通用的特性:
属性 | 说明 | 默认 | Presence |
---|---|---|---|
name |
政策的内部名称。 (可选)使用 |
不适用 | 必需 |
continueOnError |
设置为 设置为 |
false | 可选 |
enabled |
设置为 设为 |
true | 可选 |
async |
此特性已弃用。 |
false | 已弃用 |
<DisplayName> 元素
用于在 name
属性之外在管理界面代理编辑器中给政策添加不同的自然语言名称标签。
<DisplayName>Policy Display Name</DisplayName>
默认 |
不适用 如果省略此元素,则会使用政策的 |
---|---|
Presence | 可选 |
类型 | 字符串 |
<Source> 元素
指定要转换为 JSON 的 XML 消息的变量。
源消息的 HTTP Content-type 标头必须设置为 application/xml
,否则政策不会强制执行。
如果未定义 <Source>
,则系统会将其视为 message
,如果政策附加到请求流则解析为 request
,如果政策附加到响应流则解析为 response
。
如果源变量无法解析或解析为非消息类型,则政策会提示错误。
<Source>response</Source>
默认 | Source 元素的值 |
---|---|
Presence | 可选 |
类型 | 消息 |
<OutputVariable> 元素
指定 XML 到 JSON 格式转换的输出的存储位置。通常,政策配置中不包含此元素。
Apigee 会解析 Source
中指定的 XML 消息的载荷,将其转换为 JSON,将结果存储到 OutputVariable
的载荷中,并将 OutputVariable
消息的 HTTP Content-type 标头设置为 application/json
。
如果未指定 OutputVariable
,则默认使用 Source
的值。例如,如果 source
为 response
,则 OutputVariable
默认为 response
。
<OutputVariable>response</OutputVariable>
默认 | Source 中指定的消息 |
---|---|
Presence | 可选 |
类型 | 消息 |
<选项>
您可以使用选项来控制从 XML 到 JSON 的转换。您可以使用 <Options>
组(用于添加特定转化设置)或 <Format>
元素(用于引用预定义选项的模板)。您不能同时使用 <Options>
和 <Format>
。
如果未使用 <Format>
,则需要使用 <Options>
。
<RecognizeNumber> 元素
如果为 true,则 XML 载荷中的数字字段将保留其原始格式。
<RecognizeNumber>true</RecognizeNumber>
请参考以下 XML 示例:
<a> <b>100</b> <c>value</c> </a>
如果 RecognizeNumber
为 true
,政策会将此示例转换为:
{ "a": { "b": 100, "c": "value" } }
如果 RecognizeNumber
为 false
,政策会将此示例转换为:
{ "a": { "b": "100", "c": "value" } }
默认 | false |
---|---|
Presence | 可选 |
类型 | 布尔值 |
<RecognizeBoolean> element
让转化保留布尔值 true/false 值,而不是将值转换为字符串。
<RecognizeBoolean>true</RecognizeBoolean>
对于以下 XML 示例:
<a> <b>true</b> <c>value</c> </a>
如果 RecognizeBoolean
为 true
,政策会将此示例转换为:
{ "a": { "b": true, "c": "value" } }
如果 RecognizeBoolean
为 false
,政策会将此示例转换为:
{ "a": { "b": "true", "c": "value" } }
默认 | false |
---|---|
Presence | 可选 |
类型 | 布尔值 |
<RecognizeNull> 元素
允许您将空值转换为 null 值。
<RecognizeNull>true</RecognizeNull>
对于以下 XML:
<a> <b></b> <c>value</c> </a>
如果 RecognizeNull
为 true
,如果没有 NullValue
选项,则此 XML 将转换为:
{ "a": { "b": null, "c": "value" } }
如果 RecognizeNull
为 false
,则此 XML 将转换为:
{ "a": { "b": {}, "c": "value" } }
默认 | false |
---|---|
Presence | 可选 |
类型 | 布尔值 |
<NullValue> 元素
表示源消息中已识别的 null 值应转换为的值。默认情况下,值为 null
。只有当 RecognizeNull
为 true 时,此选项才有效。
<NullValue>not-present</NullValue>
对于以下 XML:
<a> <b></b> <c>value</c> </a>
如果 RecognizeNull
为 true
且未指定 NullValue
,则此 XML 将转换为:
{ "a": { "b": null, "c": "value" } }
如果 RecognizeNull
为 true
,且 NullValue
为 not-present
,则此 XML 将转换为:
{ "a": { "b": "not-present", "c": "value" } }
默认 | null |
---|---|
Presence | 可选 |
类型 | 字符串 |
命名空间选项
默认情况下,此政策会在生成的 JSON 中省略 XML 命名空间。如需指定 XML 文档中的命名空间应转换为生成的 JSON,请将共同使用这些元素。
<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> ,则无论源消息是否引用命名空间,政策都将生成不引用任何 XML 命名空间的输出 JSON。 |
---|---|
Presence | 可选 但是,如果您指定 <NamespaceBlockName> ,则还必须指定另外两个元素。 |
类型 | 字符串 |
文本选项
一起使用这些元素。
<TextAlwaysAsProperty>true|false</TextAlwaysAsProperty> <TextNodeName>TEXT</TextNodeName>
当政策遇到仅包含单个文本子节点的 XML 元素时,政策会将该 XML 元素的文本内容转换为 JSON 哈希中的属性。
当政策遇到包含多个混合内容子节点的 XML 元素时,您可以使用这些选项控制任何子文本节点的输出 JSON。
例如,考虑此政策配置:
<XMLToJSON name='XMLToJSON-1'> <Options> <TextAlwaysAsProperty>???</TextAlwaysAsProperty> <TextNodeName>#text</TextNodeName> </Options> </XMLToJSON>
对于给定的 XML 输入,根据 TextAlwaysAsProperty
是 true
还是 false
,政策会生成以下输出:
XML 输入 | JSON 输出 | |
---|---|---|
TextAlwaysAsProperty 为 false |
TextAlwaysAsProperty 为 true |
|
<a>value1</a> |
{ "a": "value1" } |
{ "a": { "#text": "value1" } } |
<a>value1 <b>value2</b> </a> |
{ "a": { "#text": "value1\n", "b": "value2" } } |
{ "a": { "#text": "value1\n", "b": { "#text": "value2" } } } |
默认 | <TextAlwaysAsProperty> :false<TextNodeName> :(空白字符串) |
---|---|
Presence | 可选 |
类型 | <TextAlwaysAsProperty> :布尔值<TextNodeName> :字符串 |
属性选项
通过将这些元素一起使用,您可以将属性值分组到 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" } }
默认 | 无。 |
---|---|
Presence | 可选 |
类型 | 字符串 |
<OutputPrefix> 和 <OutputSuffix> 元素
您可以共同使用这些元素来将前缀和/或后缀应用于生成的 JSON。
<OutputPrefix>PREFIX_</OutputPrefix> <OutputSuffix>_SUFFIX</OutputSuffix>
请参考以下 XML 示例:
<a>value</a>
假设政策配置如下所示:
<XMLToJSON name='XMLToJSON-4'> <Options> <OutputPrefix>{ "result": </OutputPrefix> <OutputSuffix>}</OutputSuffix> </Options> </XMLToJSON>
生成以下 JSON 结构:
{ "result": { "a": "value" } }
您可以省略 OutputPrefix
和/或 OutputSuffix
。
使用这些元素时,有可能会生成无效的 JSON。例如,使用此政策配置:
<XMLToJSON name='XMLToJSON-4'> <Options> <OutputPrefix>PREFIX_</OutputPrefix> </Options> </XMLToJSON>
政策会生成以下结构,这不是有效的 JSON:
PREFIX_{ "a" : "value" }
如果配置既未指定 OutputPrefix
,也未指定 OutputSuffix
,则政策会生成以下 JSON 结构:
{ "a": "value" }
默认 | 请参阅上文中的示例。 |
---|---|
Presence | 可选 |
类型 | 字符串 |
<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(无级别删除) |
---|---|
Presence | 可选 |
类型 | 整数 |
<TreatAsArray>/<Path> 元素
<Options> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
此元素组合可确保 XML 文档中的值始终转换为 JSON 数组。当不同载荷有不同数量的子元素时,此功能非常有用。Apigee 的默认行为是将多个同名的子元素转换为 JSON 数组,并将单个子元素转换为 JSON 原始类型。TreatAsArray
选项可以确保子元素始终转换为 JSON 数组。
使用 TreatAsArray
可以改善处理输出的后续代码的结构,因为数组中的数据每次返回的方式都相同。例如,对 JSONPath $.teachers.teacher.studentnames.name[0]
求值将始终返回第一个 name 值,无论原始 XML 是包含一个还是多个 name
元素。
让我们退后一步并看看 XML 到 JSON 的默认行为,然后探索如何使用 <TreatAsArray>/<Path>
控制输出。
如果 XML 文档包含的一个元素多次出现(当 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" ] } } } }
可以看到,两个学生姓名放在一个数组中。
但是,如果 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
属性,下一部分会对此进行介绍。
默认 | 不适用 |
---|---|
Presence | 可选 |
类型 | 字符串 |
属性
<Options> <TreatAsArray> <Path unwrap="true">teachers/teacher/studentnames/name</Path> </TreatAsArray> </Options>
属性 | 说明 | Presence | 类型 |
---|---|---|---|
取消封装 |
默认值: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"] }]... 请注意,由于 |
可选 | 布尔值 |
如需查看更多示例和功能演示,请参阅这篇 Google Cloud 社区文章。
<格式>
格式让您能够控制从 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 |
Presence | 可选,但如果未使用 <Options> ,则为必需。 |
类型 | 字符串 |
架构
错误参考信息
This section describes the fault codes and error messages that are returned and fault variables that are set by Apigee 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 |
ExecutionFailed |
This error occurs when the input payload (XML) is empty or the input XML is invalid or malformed. | build |
steps.xmltojson.InCompatibleTypes |
ExecutionFailed |
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 |
ExecutionFailed |
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 |
ExecutionFailed |
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 |
ExecutionFailed |
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:JSONtoXML 政策