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_Entry
s, that's why I'm working with a combination of functions to obtain dynamically the keys and values.