Mulesoft DataWeave 2.0-有条件地更改单个嵌套值

时间:2020-10-25 01:47:55

标签: xml dataweave mulesoft

XML的状态需要更改,然后才能转发。如果RESPONSE.OUTBOUND.STATUS等于“ ERR”,则需要改为“ FAILURE”。 STATUS可能包含的其他消息必须保持原样。

处理之前对XML进行采样:

<?xml version="1.0" encoding="UTF-8"?>
<RESPONSE>
   <ID>9497585</ID>
   <DATE>2020-10-01</DATE>
   <TIME>18:38:04</TIME>
   <OUTBOUND>
      <CODE>921</CODE>
      <STATUS>ERR</STATUS>
      <DESC>Manufacturing flaw</DESC>
   </OUTBOUND>
   <ORIGIN>
      <METHOD>POST</METHOD>
      <STATUS>200 OK</STATUS>
      <CLIENTID>29834</CLIENTID>
      <DIAG>330</DIAG>
      <NOTES>XRAY revealed air pockets.</NOTES>
   </ORIGIN>
</RESPONSE>

DataWeave:

%dw 2.0
output application/xml
---
payload 
   - "RESPONSE" ++
   { "RESPONSE" : 
        (payload.RESPONSE - "OUTBOUND") ++
        { "OUTBOUND" : 
            (payload.RESPONSE.OUTBOUND - "STATUS") ++ 
            {"STATUS" : 
               if (payload.RESPONSE.OUTBOUND.STATUS == "ERR") 
                  "FAILURE"  
               else 
                  payload.RESPONSE.OUTBOUND.STATUS
            } 
        }
   } 

这是输出:

<?xml version='1.0' encoding='UTF-8'?>
<RESPONSE>
  <ID>9497585</ID>
  <DATE>2020-10-01</DATE>
  <TIME>18:38:04</TIME>
  <ORIGIN>
    <METHOD>POST</METHOD>
    <STATUS>OK</STATUS>
    <CLIENTID>29834</CLIENTID>
    <DIAG>330</DIAG>
    <NOTES>XRAY revealed air pockets.</NOTES>
  </ORIGIN>
  <OUTBOUND>
    <CODE>921</CODE>
    <DESC>Manufacturing flaw</DESC>
    <STATUS>FAILURE</STATUS>
  </OUTBOUND>
</RESPONSE>

这在某种程度上起作用,但是更改单个值似乎不必要地复杂。这就像使用大锤,因为我找不到手术刀。有没有更简单的方法可以到达节点并进行更改?

此外,XML依赖于节点顺序。通过删除然后重新插入子节点,我最终更改了节点的顺序(“ OUTBOUND”现在出现在“ ORIGIN”之后)。这可能会在以后造成悲伤。

6 个答案:

答案 0 :(得分:2)

最简单的方法是使用update运算符

%dw 2.0
output application/xml
---
payload update {
    case status at .RESPONSE.OUTBOUND.STATUS if(status == "ERR") ->  "FAILURE"
}

简单清晰;)

答案 1 :(得分:2)

使用update函数,Mariano也为我提供了另一种解决方案。

该函数需要以数组格式描述的元素的路径。

该问题的答案正在下雨:)。

%dw 2.0
import update from dw::util::Values
output application/xml
---
payload  update ["RESPONSE", "OUTBOUND", "STATUS"] with (value) -> if(value == "ERR") "Failure" else value 

答案 2 :(得分:0)

这应该有帮助。

%dw 2.0
output application/xml
fun replaceElementValue(value:Any, nametoReplace: String, newValue: Any) = do {
    value match {
        case obj is Object -> obj mapObject ((value, key, index) -> 
            if(key ~= nametoReplace and value == "ERR")
                (key): newValue
            else    
                (key) : replaceElementValue(value, nametoReplace, newValue)
        )
        else -> value
    }
}   
---
replaceElementValue(payload,"STATUS","FAILRUE")

稍微修改了here中提到的脚本,以帮助您实现所需的功能。

enter image description here

答案 3 :(得分:0)

扩展您的尝试。保留节点的顺序尝试使用此脚本。

%dw 2.0
output application/xml
var outbound = payload.RESPONSE - "ORIGIN"
var origin  = payload.RESPONSE - "OUTBOUND" - "ID" - "DATE" - "TIME"
---
{
 a: outbound - "OUTBOUND" ++ { "OUTBOUND" : 
            (payload.RESPONSE.OUTBOUND - "STATUS") ++ 
            {"STATUS" : 
               if (payload.RESPONSE.OUTBOUND.STATUS == "ERR") 
                  "FAILURE"  
               else 
                  payload.RESPONSE.OUTBOUND.STATUS
            } 
        } ++
        origin
}

答案 4 :(得分:0)

如果您不希望其他标签具有ERR值,则可以使用以下两个功能之一:

%dw 2.0
output application/xml

var data = read(
'<?xml version="1.0" encoding="UTF-8"?>
<RESPONSE>
   <ID>9497585</ID>
   <DATE>2020-10-01</DATE>
   <TIME>18:38:04</TIME>
   <OUTBOUND>
      <CODE>921</CODE>
      <STATUS>ERR</STATUS>
      <DESC>Manufacturing flaw</DESC>
   </OUTBOUND>
   <ORIGIN>
      <METHOD>POST</METHOD>
      <STATUS>200 OK</STATUS>
      <CLIENTID>29834</CLIENTID>
      <DIAG>330</DIAG>
      <NOTES>XRAY revealed air pockets.</NOTES>
   </ORIGIN>
</RESPONSE>',
"application/xml"
)

// Traverse the XML and replace the String ERR with FAILURE
fun traverse(o: Object) = o mapObject (
    if ($$ ~= "OUTBOUND") {($$): traverse($)} else {($$):$}
)
fun traverse(s: String) = (
    if (s == "ERR") "FAILURE" else s
)

// Decouple the replacement from the traversal.  This is a more
// flexible solution
fun traverseFn(o: Object,fn, tag: String = "OUTBOUND") = o mapObject (
    if ($$ ~= tag) {($$): ($ traverseFn fn)} else {($$): $}
)
fun traverseFn(s: String, fn) = fn(s)

---
//traverse(data)

data traverseFn (
    (s) -> s match {
        case "ERR" -> "FAILURE"
        else -> $
    }
)

答案 5 :(得分:0)

尝试一下-

使用update功能-已记录here

%dw 2.0
import * from dw::util::Values
output application/xml
var resp = payload.RESPONSE - "OUTBOUND" - "ORIGIN"
var outbound = if(payload.RESPONSE.OUTBOUND.STATUS == "ERR") (payload.RESPONSE.OUTBOUND update "STATUS" with "FAILURE") else (payload.RESPONSE.OUTBOUND)
var origin  = payload.RESPONSE - "OUTBOUND" - "ID" - "DATE" - "TIME"
---
{
    RESPONSE: resp ++ {OUTBOUND: outbound}  ++ origin
}