WSO2 EI 6.5.0中动态迭代BigQuery返回的嵌套JSON数组
如何在WSO2 EI的Iterator中动态遍历BigQuery返回的JSON数据?
问题背景
调用BigQuery API后得到如下格式的JSON响应:
{ "kind": "bigquery#queryResponse", "schema": { "fields": [ { "name": "Name", "type": "STRING", "mode": "NULLABLE" }, { "name": "Age", "type": "INTEGER", "mode": "NULLABLE" } ] }, "jobReference": { "projectId": "testbig-235116", "jobId": "job_GECobzPaLdbBW-SqIG-WrfOzaqtQ", "location": "US" }, "totalRows": "2", "rows": [ { "f": [ { "v": "John" }, { "v": "45" } ] }, { "f": [ { "v": "Harry" }, { "v": "25" } ] } ], "totalBytesProcessed": "670", "jobComplete": true, "cacheHit": false }
需要在WSO2 EI的iterate中介中遍历rows数组,提取每行数据存入property,用于后续数据库写入等操作。原代码使用json-eval($.rows[*].f)作为迭代表达式,但日志无法正确输出值,静态表达式(如rows[0].f[0].v)能取值但无法适配动态多行场景。
解决方案
1. 修正迭代表达式与取值逻辑
原代码的问题在于迭代表达式直接指向了rows[*].f,导致每个迭代的上下文是字段值数组而非完整行对象。推荐修改为遍历rows数组,这样每个迭代处理单个完整的行结构:
修正后的代码示例
<iterate expression="json-eval($.rows[*])" id="BigQID" sequential="true"> <target> <sequence> <log level="custom"> <property name="迭代内日志" value="进入Iterator处理行数据"/> <property expression="json-eval($.f[0].v)" name="Name"/> <property expression="json-eval($.f[1].v)" name="Age"/> </log> <!-- 将行数据存入property,供后续使用 --> <property expression="json-eval($.f[0].v)" name="NameProperty" scope="default" type="STRING"/> <property expression="json-eval($.f[1].v)" name="AgeProperty" scope="default" type="INTEGER"/> <!-- 示例:写入数据库(需配置对应数据源) --> <dbreport> <connection> <pool> <dsName>YourDatabaseDS</dsName> </pool> </connection> <statement> <sql><![CDATA[INSERT INTO user_info (name, age) VALUES (?, ?)]]></sql> <parameter expression="$ctx:NameProperty" type="VARCHAR"/> <parameter expression="$ctx:AgeProperty" type="INTEGER"/> </statement> </dbreport> </sequence> </target> </iterate>
2. 保留原迭代表达式的适配方案
如果坚持使用rows[*].f作为迭代表达式,需要调整取值逻辑,因为此时每个迭代的上下文是字段值数组(如[{"v":"John"},{"v":"45"}]):
<iterate expression="json-eval($.rows[*].f)" id="BigQID" sequential="true"> <target> <sequence> <log level="custom"> <property name="迭代内日志" value="进入Iterator处理行数据"/> <property expression="json-eval($.[0].v)" name="Name"/> <property expression="json-eval($.[1].v)" name="Age"/> </log> <!-- 存储property --> <property expression="json-eval($.[0].v)" name="NameProperty" scope="default" type="STRING"/> <property expression="json-eval($.[1].v)" name="AgeProperty" scope="default" type="INTEGER"/> <!-- 后续数据库操作逻辑 --> </sequence> </target> </iterate>
关键说明
- 添加
sequential="true"确保行数据按顺序处理,避免并发写入数据库时的顺序问题。 - 若需要适配动态列数(列名/数量不固定),可以先提取
schema.fields到property,再通过Script Mediator(如JavaScript)动态遍历字段值并映射到列名,实现通用化处理。
内容的提问来源于stack exchange,提问作者Justin
相关产品推荐
相关产品推荐

