I have a weird case that I need help with: I have a XML document that I wish to take to JSON using DW, which is easy, but I also wish to take some attributes and paste some parts of the original XML content as their values, to avoid interface issues down my work pipeline.
More specifically, I wish to take all of the elements of a specific tag that conform a list of that type of elements and return the same list in XML as a string. An example scenario would look like this:
Input
<bookstore>
  <book category="cooking">
    <title lang="en">Everyday Italian</title>
    <author>Giada De Laurentiis</author>
    <year>2005</year>
    <price>30.00</price>
  </book>
  <book category="children">
    <title lang="en">Harry Potter</title>
    <author>J K. Rowling</author>
    <year>2005</year>
    <price>29.99</price>
  </book>
</bookstore>
Output
{"book": "<book category=\"cooking\"><title lang=\"en\">EverydayItalian</title><author>Giada De Laurentiis</author><year>2005</year><price>30.00</price></book><book category=\"children\"><title lang=\"en\">Harry Potter</title><author>J K. Rowling</author><year>2005</year><price>29.99</price></book>"}
This is how far I arrived to a close solution. Report_Data and Report_Entry are just wrapping the information in this case. I expect to receive various Report_Entry elements so this is still a draft.
%dw 2.0
import * from dw::core::Types
import mergeWith from dw::core::Objects
input payload xml
output application/json
var literalKeys = (namesOf(payload.Report_Data.Report_Entry) distinctBy ((item, index) -> item)) filter ((item) -> not isObjectType(typeOf(payload.Report_Data.Report_Entry[item])))
var objectKeys = (namesOf(payload.Report_Data.Report_Entry) distinctBy ((item, index) -> item)) filter ((item) -> isObjectType(typeOf(payload.Report_Data.Report_Entry[item])))
var allObjects = payload.Report_Data.Report_Entry filterObject((value, key, index) -> objectKeys reduce ((item, accumulator = false) -> (key ~= item) or accumulator))
var justTheScalars = payload.Report_Data.Report_Entry filterObject((value, key, index) -> not (objectKeys reduce ((item, accumulator = false) -> (key ~= item) or accumulator)))
var groupedAllObjects = allObjects groupBy (item, index) -> index
---
justTheScalars mergeWith (groupedAllObjects)
I got to a the point were I can
- Determine which keys correspond to objects and which to literals
- Divide all objects and all scalars inside from my input
- Group the objects together according to their class and returned the merge object
But I still miss the part where I can somehow take the input and paste is as a string or transform it somehow into a string to avoid information loss as much as I can.
Please take into account this case is a particular one for the usage of DW, as I have no information about what will come inside the different Report_Entrys, that's why I'm working with a combination of functions to obtain dynamically the keys and values.
 
     
    