cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
Showing results for 
Search instead for 
Did you mean: 

Parsing XML Data (especially if it's SOAP)

Highlighted

Parsing XML Data (especially if it's SOAP)

Recently I needed to be able to parse and handle XML data natively inside of a ThingWorx script, and this XML file happened to have a SOAP namespace as well. I learned a few things along the way that I couldn’t find a lot of documentation on, so am sharing here.

 

Lessons Learned

  1. The biggest lesson I learned is that ThingWorx uses “E4X” XML handling. This is a language that Mozilla created as a way for JavaScript to handle XML (the full name is “ECMAscript for XML”). While Mozilla deprecated the language in 2014, Rhino, the JavaScript engine that ThingWorx uses on the server, still supports it, so ThingWorx does too. Here’s a tutorial on E4X - https://developer.mozilla.org/en-US/docs/Archive/Web/E4X_tutorial
  2. The built-in linter in ThingWorx will complain about E4X syntax, but it still works.
  3. I learned how to get to the data I wanted and loop through to create an InfoTable. Hopefully this is what you want to do as well.

 

Selecting an Element and Iterating

  1. My data came inside of a SOAP envelope, which was meaningless information to me. I wanted to get down a few layers. Here’s a sample of my data that has made-up information in place of the customer's original data:               
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" headers="">
        <SOAP-ENV:Body>
            <get_part_schResponse xmlns="urn:schemas-iwaysoftware-com:iwse">
                <get_part_schResult>
                    <get_part_schRow>
                        <PART_NO>123456</PART_NO>
                        <ORD_PROC_DIV_CD>E</ORD_PROC_DIV_CD>
                        <MFG_DIV_CD>E</MFG_DIV_CD>
                        <SCHED_DT>2020-01-01</SCHED_DT>
                    </get_part_schRow>
                    <get_part_schRow>
                        <PART_NO>789456</PART_NO>
                        <ORD_PROC_DIV_CD>E</ORD_PROC_DIV_CD>
                        <MFG_DIV_CD>E</MFG_DIV_CD>
                        <SCHED_DT>2020-01-01</SCHED_DT>
                    </get_part_schRow>
                </get_part_schResult>
            </get_part_schResponse>
        </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>
  2. To get to the schRow data, I need to get past SOAP and into a few layers of XML. To do that, I make a new variable and use the E4X selections to get there:
    var data = resultXML.*::Body.*::get_part_schResponse.*::get_part_schResult.*;
    1. Note a few things:
      1. resultXML is a variable in the service that contains the XML data.
      2. I skipped the Envelope tag since that’s the root.
      3. The .* syntax does not mean “all the following”, it means “all namespaces”. You can define and specify the namespaces instead of using .*, but I didn’t find value in that. I found some sample code that theoretically should work on a VMware forum: https://communities.vmware.com/thread/592000.
    2. This gives me schRow as an XML List that I can iterate through. You can see what you have at this point by converting the data to a String and outputting it:
      var result = String(data);
  3. Now that I am to the schRow data, I can use a for loop to add to an InfoTable:
    for each (var row in data) { 
        result.AddRow({
            PartNumber: row.*::PART_NO,
            OrderProcessingDivCD: row.*::ORD_PROC_DIV_CD,
            ManufacturingDivCD: row.*::MFG_DIV_CD,
            ScheduledDate: row.*::SCHED_DT
        });
    }
  4. Shoo! That’s it! Data into an InfoTable! Next time, I'll ask for a JSON API.
1 REPLY 1
Highlighted

Re: Parsing XML Data (especially if it's SOAP)

Very cool. should also add the @ part as well when you have multiple elements within a row.

Announcements