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