在 dataweave 中读取 json 负载作为 CSV 文件的一部分

Reading json Payload as part of a CSV file in dataweave

我有一个 Web 服务,它导出一个 CSV 文件,其中有一个列作为 JSON 负载。执行 Web 服务后,我将值存储在局部变量中以进行转换。每次当我从该列读取值时,我都会丢失这些值,并且只返回“}”。不知道为什么会这样。我想按原样保留 JSON 有效负载,并在经过一些处理后保存到文件中。请指教

我正在使用下面的代码获取属性列的值,它总是 returns 一个“}”。其余内容忽略

CSV Fragment
-------------
 id,name,attributes
 1,name1,{"Choice Number":"0","Campaign Run Id":"234"}
 2,name2,{"Choice Number":"1","Campaign Run Id":"235"}
 3,name3,{"Choice Number":"2","Campaign Run Id":"236"}
 4,name4,{"Choice Number":"3","Campaign Run Id":"236"}


Code
----
 %dw 1.0
 %output application/java
 ---
 flowVars.activityData map ((actData) -> {
      "playerId": actData.id,
      "name": actData.name,
      "attributes": actData.attributes
  })

我原以为属性列中的完整 JSON 负载会被返回,但事实并非如此。我在这里注意到的一件事是,输入中的 JSON 有效负载中没有字符转义。但我对此也没有任何控制权。在这种情况下如何从属性列中提取信息


由于我无法共享整个项目,因此创建了一个示例项目并使用来自@machaval 的输入和接收 csv 文件的 http 对象。将 mimetype 标记为 text/csv 并发送 payload

<?xml version="1.0" encoding="UTF-8"?>

<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:tracking="http://www.mulesoft.org/schema/mule/ee/tracking" xmlns:file="http://www.mulesoft.org/schema/mule/file" xmlns:dw="http://www.mulesoft.org/schema/mule/ee/dw" xmlns="http://www.mulesoft.org/schema/mule/core" xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
    xmlns:spring="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-current.xsd
http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/file http://www.mulesoft.org/schema/mule/file/current/mule-file.xsd
http://www.mulesoft.org/schema/mule/ee/dw http://www.mulesoft.org/schema/mule/ee/dw/current/dw.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/ee/tracking http://www.mulesoft.org/schema/mule/ee/tracking/current/mule-tracking-ee.xsd">
    <http:listener-config name="HTTP_Listener_Configuration" host="0.0.0.0" port="8081" doc:name="HTTP Listener Configuration"/>
    <flow name="CSVFlow">
        <http:listener config-ref="HTTP_Listener_Configuration" path="/process" doc:name="HTTP"/>
        <object-to-string-transformer doc:name="Object to String"/>
        <dw:transform-message doc:name="Transform Message">
            <dw:set-payload><![CDATA[%dw 1.0
%output application/json
---
//First remove the header
(payload splitBy "\n")[1 to -1] 
    map ((item, index) -> using(commas = item find ",")             
        {
            id: item[0 to commas[0] - 1],
            name: item[commas[0] + 1 to commas[1] - 1],
            attributes: item[commas[1] + 1 to -1]
        }
    )]]></dw:set-payload>
        </dw:transform-message>
    </flow>

</mule>

您好 Rajeev,您的数据存在问题,它不是 CSV,json 需要以某种方式进行转义。所以我解决你问题的方法是将你的输入作为字符串处理(这可以通过使用对象来字符串 mp 轻松完成)并手动解析它。我的假设是您的格式没有更多技巧。

%dw 1.0
output application/json  
---
//First remove the header
(payload splitBy "\n")[1 to -1] 
    map ((item, index) -> using(commas = item find ",")             
        {
            id: item[0 to commas[0] - 1],
            name: item[commas[0] + 1 to commas[1] - 1],
            attributes: item[commas[1] + 1 to -1]
        }
    )

有一个问题 - csv(, ") 中的特殊字符被引号括起来。如果超过一列的值中有多个引号和逗号,上述解决方案将失败。我冒昧地修改了解决方案并对其进行一些调整:

%dw 2.0
output application/java
import * from dw::core::Arrays
var headerRow = (data) -> ((data splitBy "\n")[0]) splitBy ","
var dataRows = (data) -> (data splitBy "\n")[1 to -1]
---
dataRows(payload) map (dataRow,index) -> 
do 
{
    var commas = dataRow find ","
    var indices = flatten(dataRow find /(?<!")"(?!")/)
    var quoteposition = 

            indices map 
            (
                (item, index) -> 
                (
                    {
                        (start:item) if isEven(index),
                        (end:indices[index + 1]) if isEven(index)
                    }
                ) 

            ) filter $ != null and $ != {}

    fun removeCommasinQuotes(c: Array<Number>, q: Array<{|start?: Number, end?: Number|}>) =  c filter (item,index) -> !(q some (item > $.start and item < $.end))
    var separator = removeCommasinQuotes(commas,quoteposition)
    ---
    {
        (headerRow(payload)[0]): dataRow[0 to separator[0] - 1],
        (headerRow(payload)[1]):dataRow[separator[0] + 1 to separator[1] - 1],
        (headerRow(payload)[2]):dataRow[separator[1] + 1 to separator[2] - 1],
        (headerRow(payload)[3]):dataRow[separator[2] + 1 to separator[3] - 1],
        (headerRow(payload)[4]):dataRow[separator[3] + 1 to separator[4] - 1],
        (headerRow(payload)[5]):dataRow[separator[4] + 1 to separator[5] - 1],
        (headerRow(payload)[6]):dataRow[separator[5] + 1 to separator[6] - 1],
        (headerRow(payload)[7]):dataRow[separator[6] + 1 to separator[7] - 1],
        (headerRow(payload)[8]):dataRow[separator[7] + 1 to -1]

    }

}