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

Mulesoft DataWeave 2.0 - conditionally change a single nested value

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>

数据编织:

%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”之后)。这可能会在未来造成悲伤。

这应该有所帮助。

%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 以帮助实现您正在寻找的内容。

延长你的尝试时间。保留节点的顺序尝试使用此脚本。

%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
}

如果您不希望任何其他标签具有 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 -> $
    }
)

试试这个 -

使用 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
}

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

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

简单明了;)

使用 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