繁体   English   中英

Mulesoft Dataweave 2.0 尝试将 JSON 转换为 XML 有效负载的问题

[英]Mulesoft Dataweave 2.0 Issue trying to transform JSON to XML payload with attributes

我对 Dataweave 比较陌生,我正在尝试在将 JSON 映射到 XML 有效负载时解决转换问题。 我现在只有一条带有output application/xml 的 Transform 消息。

我需要能够接受几个不同的大型 JSON 有效载荷。 我不会提前知道每个结构的结构是什么,但我需要以某种方式 map 属性。

这是我的输入的示例片段:

"HomeLineBusiness": { 
    "Dwell": {
         "@LocationRef": "e3654502-524f-4834-b872-272d77a84f1b",
         "@id": "c263e3e1-750b-4562-81c3-deb6eee6f1c5",
         "PrincipalUnitAtRiskInd": "1",
         "PolicyTypeCd": "03",
    }
}

这是转换后当前返回的内容:

<HomeLineBusiness>
        <Dwell>
                <@LocationRef>e3654502-524f-4834-b872-272d77a84f1b</@LocationRef>
                <@id>c263e3e1-750b-4562-81c3-deb6eee6f1c5</@id>
                <PrincipalUnitAtRiskInd>1</PrincipalUnitAtRiskInd>
                <PolicyTypeCd>03</PolicyTypeCd>
        </Dwell>
</HomeLineBusiness>

这就是我需要它转换的方式:

<HomeLineBusiness>
        <Dwell LocationRef="e3654502-524f-4834-b872-272d77a84f1b" id="c263e3e1-750b-4562-81c3-deb6eee6f1c5">
                <PrincipalUnitAtRiskInd>1</PrincipalUnitAtRiskInd>
                <PolicyTypeCd>03</PolicyTypeCd>
        </Dwell>
</HomeLineBusiness>

任何以 @ 开头的标签都需要映射为属性。 我不知道我是否可以做一个替换结构或者是否有其他推荐的方法。

谢谢

使用模式匹配,您可以使用 filterObject() 和 mapObject 来选择要转换为元素的值以及要转换为属性的值。 条件是键是否以@字符开头。 我创建了一个函数来简化从列表中提取我们想要的属性。 这会产生一个对象,该对象可直接用于使用@((...))构造(即@((getAttributes($))) )在正确级别设置属性。

使用递归函数来驱动转换允许它是动态的并且可以处理包括数组在内的多个级别的结构。

%dw 2.0
output application/xml
fun getAttributes(x)=
        x match {
        case is Object -> x filterObject ($$ as String startsWith "@") 
                     mapObject ((value, key, index) -> (key[1 to -1] ): value)
        else -> $
  }
fun convertToAttributes(x)=                   
    x match  {
        case is Object -> x filterObject !($$ as String startsWith "@")
                            mapObject ($$) @((getAttributes($))): convertToAttributes($)
        case is Array -> x map convertToAttributes($)
        else -> $
  }
---
convertToAttributes(payload)

输入:

{
    "HomeLineBusiness": { 
        "Dwell": {
            "@LocationRef": "e3654502-524f-4834-b872-272d77a84f1b",
            "@id": "c263e3e1-750b-4562-81c3-deb6eee6f1c5",
            "PrincipalUnitAtRiskInd": "1",
            "PolicyTypeCd": "03"
        }
    }
}

输出:

<?xml version='1.0' encoding='UTF-8'?>
<HomeLineBusiness>
  <Dwell LocationRef="e3654502-524f-4834-b872-272d77a84f1b" id="c263e3e1-750b-4562-81c3-deb6eee6f1c5">
    <PrincipalUnitAtRiskInd>1</PrincipalUnitAtRiskInd>
    <PolicyTypeCd>03</PolicyTypeCd>
  </Dwell>
</HomeLineBusiness>

虽然 aled 的解决方案大多是正确的。 当涉及到数组时,它有一个小错误。 它将重复数组的键及其元素。

%dw 2.0
output application/xml

fun getAttributeNode(object) = 
    object 
        filterObject ($$ as String startsWith "@") 
        mapObject ((value, key) -> {
            ((key as String replace /^@/ with "") : value)
        })
        
fun getNonAttributeNode(object) = 
    object
       filterObject (not ($$ as String startsWith "@"))
       mapObject ((value, key) -> 
         if(value is Object) getElementNode((key): value)
         else if(value is Array) (key): {(value map getElementNode($))}
         else (key): value
       )

fun getElementNode(object) = 
        object mapObject ($$) @((getAttributeNode($))) : getNonAttributeNode($)
---
getElementNode(payload)

我用这个 Payload 试过了

{
  "HomeLineBusiness": {
    "Dwell": {
      "@LocationRef": "e3654502-524f-4834-b872-272d77a84f1b",
      "@id": "c263e3e1-750b-4562-81c3-deb6eee6f1c5",
      "PrincipalUnitAtRiskInd": "1",
      "PolicyTypeCd": "03",
      "SomeNestedObjectWithAttributes": {
        "@NestedAttribute1": "NestedAttribute1",
        "@NestedAttribute2": "NestedAttribute2",
        "NestedString": "Some string value"
      },
      "SomeNestedObjectWithoutAttributes": {
        "NestedString": "Some string value"
      },
      "SomeArray": [
        {
          "ArrayElementOne": {
            "@AttributeOfArrayOne": "AttributeValueOfArrayOne",
            "@AttributeOfArrayTwo": "AttributeValueOfArrayTwo",
            "StringInArrayOne": "String value of Array One"
          }
        },
        {
          "ArrayElementTwo": {
            "@AttributeOfArrayTwo": "AttributeValueOfArrayTwo",
            "@AttributeOfArrayTwo": "AttributeValueOfArrayTwo",
            "StringInArrayTwo": "String value of Array Two"
          }
        }
      ]
    }
  }
}

并得到这个输出

<?xml version='1.0' encoding='UTF-8'?>
<HomeLineBusiness>
  <Dwell LocationRef="e3654502-524f-4834-b872-272d77a84f1b" id="c263e3e1-750b-4562-81c3-deb6eee6f1c5">
    <PrincipalUnitAtRiskInd>1</PrincipalUnitAtRiskInd>
    <PolicyTypeCd>03</PolicyTypeCd>
    <SomeNestedObjectWithAttributes NestedAttribute1="NestedAttribute1" NestedAttribute2="NestedAttribute2">
      <NestedString>Some string value</NestedString>
    </SomeNestedObjectWithAttributes>
    <SomeNestedObjectWithoutAttributes>
      <NestedString>Some string value</NestedString>
    </SomeNestedObjectWithoutAttributes>
    <SomeArray>
      <ArrayElementOne AttributeOfArrayOne="AttributeValueOfArrayOne" AttributeOfArrayTwo="AttributeValueOfArrayTwo">
        <StringInArrayOne>String value of Array One</StringInArrayOne>
      </ArrayElementOne>
    </SomeArray>
    <SomeArray>
      <ArrayElementTwo AttributeOfArrayTwo="AttributeValueOfArrayTwo" AttributeOfArrayTwo="AttributeValueOfArrayTwo">
        <StringInArrayTwo>String value of Array Two</StringInArrayTwo>
      </ArrayElementTwo>
    </SomeArray>
  </Dwell>
</HomeLineBusiness>

将您的输入有效负载转换为文本并试试这个,

%dw 2.0
var Data = payload replace '@' with ""
output application/xml  
---
  HomeLineBusiness: do {
    var myVar = (read(Data, "application/xml")).HomeLineBusiness
    ---

      Dwell @(LocationRef: myVar.Dwell.LocationRef, id: myVar.Dwell.id): {
        PrincipalUnitAtRiskInd: myVar.Dwell.PrincipalUnitAtRiskInd,
        PolicyTypeCd: myVar.Dwell.PolicyTypeCd
      }

  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM