Xml and datastores

Hi everyone

I am continuing my journey of trying to learn to use Make mostly through reverse engineering and trial and error…and have gotten much more proficient…but have run into a tricky problem (well…tricky for me anyways)

What I want to do:

  1. retrieve an xml file that contains an order header and line items
  2. pass back that same xml with updated acknowledgement fields
  3. when the order ships, send back an xml with invoice information. the invoice xml format is nearly identical to the order xml I received, but with several different fields (some eliminated, some added)

I’m grabbing the xml and dropping it into a datastore with a data structure defined by the xml
then i have a separate data store that is tracking status changes for each order…

all of which works fine.

But i can’t figure out the right way to transform the xml in the original order datastore to the format needed for the invoice xml

a simplified representation of what I’m trying to do…

I receive something that looks like:
< order>
< ordernum>1234< /ordernum>
< date>2023-01-01< /date>

< lines>
< item>
< sku>abc123< /sku>
< ordered>10< /ordered>
< /item>
< item>
< sku>xyz123< /sku>
< ordered>5< /ordered>
< /item>
< /line>
< /order>

and i want to send back something like:
< invoice>
< ordernum>1234< /ordernum>
< date>2023-01-01< /date>

< lines>
< item>
< sku>abc123< /sku>
< ordered>5< /ordered>
< shipped>10< /shipped>
< /item>
< item>
< sku>xyz123< /sku>
< ordered>5< /ordered>
< shipped>2< /shipped>
< /item>
< /line>
< /invoice>

some of the actual data they pass through to me only resides in their system and I just need to pass it back… so I’m storing everything in a datastore

where I’m getting a bit stuck is the best way to iterate through the line items in the xml structure (from the datastore) and then create the new invoice xml which includes both elements from the original order as well as updated data from my system.

convert the xml to an array and then manipulate it (get/map)? use the iterator/aggregator?
I’ve tried both approaches and keep getting tied in knots…I’m not really clear on how to iterate through the xml from the data store and put it back together again in the correct format

I’m not sure i’m describing the issue well enough…or if anyone has any tips on how to make this work… but any advice is greatly appreciated!!

more specifically…I can get most of what I need done by calling the data store with the original order, iterating through the lines, creating xml and then aggregating into an array and then mapping the lines in the ‘create invoice xml’ module to the output of the aggregator…like this:

But I’m getting odd formatting I can’t seem to resolve. “<” and “>” are replaced with "&lt;" and "&gt;"…there’s an extra opening and closing of the < lines> tag between each line item (the structure is < lines> then < invoice line> ) and there’s an extra < xml> as well

any suggestions truly appreciated!

instead of getting a clean
</invoice_line>
<invoice_line>

between each line item section in the xml, I’m getting:

</invoice_line>
</xml>
</lines>
<lines>
<xml>
<invoice_line>

image

so…I have progressed things, but still not sure I’m any closer.

logic: grab original order xml from data store, iterate through the lines, create line items xml, aggregate that into a table, aggregate that into an array, insert the array into a matching invoice xml to a mapped “lines” field

all of the inputs and outputs of each module look like they’re correct, but I just keep getting an “Invalid collection in parameter ‘INVOICE_LINE’.” error. when I try to insert into either the array aggregator or directly into the create xml module

ugh

OK…got it to work, even though its not pretty. leaving my ‘solution’ in case its helpful for anyone…but I think the real issue is I just don’t understand how to work with arrays effectively. I just couldn’t figure out the right way to get the xml created for each line out of the array and into the ‘full’ xml for the invoice.

What I’ve ended up doing is: get the xml from the datastore; iterate through the lines and add in the updated data required for each and turn that into xml. build a variable that concatenates the output on each iteration. Then build the Invoice xml and insert the raw text from the concatenated variable that contains the line items into the right spot of the invoice xml

if anyone has any tips on working with arrays to do this more efficiently, I’m all ears!

Hey @Noah :wave:

Awesome that you managed to figure out a way of making this work :clap: And thanks so much a lot for sharing your solution with the community, we really appreciate it.

Let’s see if someone jumps in with a different approach to this but like I said - great work!

Hey @Noah , good solution probably!
It’s a lot to read and very specific, so a bit difficult to completely help you out here; however what I think you could do is the following:

  1. Use the JSON module and create the correct structure you need, including the line_items etc.
  2. Iterate over your items, and use an “Aggregate to JSON” module to add all data into a JSON
  3. Then use the “Convert JSON to XML” module to eventually create an XML

If you have some free time give it a try :wink:
Hope this helps you in the future.

1 Like

Appreciate the feedback! I think where I’m consistently getting stuck though is in creating “nested” JSON or XML files. eg a varying number of line items inside a bigger “order”

I’ve tried both JSON and XML…and conceptually it makes sense to me (iterate through line items and create xml/json for those…then create a json or xml ‘order’ and then map the line items from the prior module to the line items in the order json/xml

…except I cant seem to make it work. it either tries to insert as a txt string, or i get a general error when it tries to run, or i can’t get things to work out in general.

is there a good tutorial for nested json/xml for Make in general? it feels like the answer is right in front of me but i just can’t see it…

Hi @Noah ,

There isn’t really a tutorial for something like this, because it’s very case specific. Each use case has a dfiferent input/output which makes it hard to create something generic.
The one thing I could usually say; use an iterator for every array you want to iterate over. Then aggregate it all together at the end, and make sure you set JSON structure.

1 Like

the answer was right in front of me! I was using the ‘create xml’ from the json, not ‘convert json to xml’ as you put in your suggestion :confused:

user error!

thanks for the help