在Enterprise Integrator 6.6.0中,我正在将XML转换为JSON有效负载。
如果XML源文件只有一个元素它显然会被当作一个对象来处理
<items>
<item></item>
</items>
是
{
"items": {
"item": {}
}
}
,但如果有更多的元素,则该特定对象被视为数组
<items>
<item></item>
<item></item>
</items>
是
{
"items": {
"item": [{}, {}]
}
}
是否有一种方法来对齐特定子对象的转换?在这种情况下,我试图总是返回一个项目数组,即使只有一个元素。
我读了关于xml-multiple
属性,但我不明白如何使用它;是否需要手动将其设置为源XML有效负载?
您可以使用Json转换中介[1]来实现您的用例。这里我们需要定义json模式来匹配预期的数据结构。对于上述情况,您将能够使用类似于以下的json模式。
{
"$schema": "http://json-schema.org/draft-04/schema#",
"type": "object",
"properties": {
"items": {
"type": "object",
"properties": {
"item": {
"type": "array",
"items": [
{
"type": "object"
}
]
}
},
"required": [
"item"
]
}
},
"required": [
"items"
]
}
指定项为数组。然后可以将模式添加到注册中心[2],并在json转换中介中引用。Json转换中介需要在xml到Json转换之后添加。请参考下面的代理服务示例。
<?xml version="1.0" encoding="UTF-8"?>
<proxy xmlns="http://ws.apache.org/ns/synapse"
name="transform"
startOnLoad="true"
statistics="disable"
trace="disable"
transports="http,https">
<target>
<inSequence>
<property name="messageType" scope="axis2" value="application/json"/>
<property name="ContentType" scope="axis2" value="application/json"/>
<jsontransform schema="conf:/schema.json"/>
<respond/>
</inSequence>
</target>
<description/>
</proxy>
输入1
<items>
<item><val1></val1></item>
<item><val1></val1></item>
</items>
输出1
{
"items": {
"item": [
{
"val1": null
},
{
"val1": null
}
]
}
}
输入2
<items>
<item><val1></val1></item>
</items>
输出2
{
"items": {
"item": [
{
"val1": null
}
]
}
}
[1] http://docs.wso2.com/display/EI660/JSON +变换+中介
[2] http://docs.wso2.com/display/EI660/Managing + +注册+
您可以像下面这样组合filterMediator
和enrichMediator
。如果没有第二项:
- 例如将
<item>
元素存储为ONE_ITEM
, - 构建
<items>
节点与<?xml-multiple item?>
, - 用已存储的
ONE_ITEM
充实新的<items>
对象。
我不知道注入<?xml-multiple item?>
XML处理指令的更好选择。下面的内容适合我。
<filter xmlns:ns="http://org.apache.synapse/xsd" xpath="not(//item[2])">
<then>
<enrich>
<source clone="false" xpath="//item"/>
<target type="property" property="ONE_ITEM"/>
</enrich>
<enrich>
<source type="inline" clone="false">
<items xmlns="">
<?xml-multiple item?>
</items>
</source>
<target xpath="//items"/>
</enrich>
<enrich>
<source type="property" clone="false" property="ONE_ITEM"/>
<target action="child" xpath="//items"/>
</enrich>
</then>
<else/>
</filter>
<property name="messageType" value="application/json" scope="axis2"/>
您可以通过在消息中添加<xsl:processing-instruction name="xml-multiple">item</xsl:processing-instruction>
来实现XSLT转换。