Parsing XML Results

When working with Web Services, the SUDS documentation and the PyDocs are a good place to start.

It's quite easy deal with return values of method calls when they are simple none structured values like floats or integers. However it's not always the case that you will have simple single values returned from a method call. Many times web services will return values that have some sort of structure to them like a dataset. Since there is no way for the web service to know how this value should be represented in the language/environment that called the method it is common that the result will be returned in an XML formatted string. Dealing with these strings is not really part of the SUDS library but an example of XML string handling is included here for completeness. This example makes use of the xml.dom.minidom python module to parse the XML string and pull out the data.

Periodic Table Example - Using xml.dom.minidom XML parsing

One of the public web services that are available has a method for returning the elements in the periodic table in a structured string. This example will show you how you can take that string result, parse through it and then create an Ignition dataset that can be displayed in a table component. The xml.dom.minidom library provides the functionality for parsing XML strings and returning what is called an XML Document (in fact DOM stands for Document Object Model). This Document has functions that allow you access the elements within the document by specifying their respective XML tags. Most of this library is out of the scope of this document but if you have any questions about the functions being used they can be found here and here.

1. The call to the web service to get the list of elements

from suds.client import Client
from xml.dom.minidom import parseString
client = Client("http://www.webservicex.net/periodictable.asmx?WSDL")
elements = client.service.GetAtoms()

2. The elements variable will now contain a structured string of the following format. We take note of this format so we will know how to parse the string.

 <NewDataSet>
<Table>
<ElementName>Actinium</ElementName>
</Table>
...
</NewDataSet>


3. Now we can parse the string and create a list of the element data

dom = parseString(xml_string)
xmlTags = dom.getElementsByTagName('ElementName')
xmlData = []
for tag in xmlTags:
xmlData.append(tag.firstChild.data)

4. The xmlData list now contains all of the names of the elements from the periodic table. Now let's get separate lists for all of the atomic numbers, atomic weights, and element numbers in the same order as our element list

element_weights = []
element_numbers = []
element_symbols = []
for name in element_names:
weight = (parseString(client.service.GetAtomicWeight(name)).getElementsByTagName('AtomicWeight')[0].firstChild.data)
number = (parseString(client.service.GetAtomicNumber(name)).getElementsByTagName('AtomicNumber')[0].firstChild.data)
symbol = (parseString(client.service.GetElementSymbol(name)).getElementsByTagName('Symbol')[0].firstChild.data)
element_weights.append(weight)
element_numbers.append(number)
element_symbols.append(symbol)


5. With our four lists we can now go about building a dataset and then use the dataset to set the data property on a table

headers = ["Name", "Symbol", "Weight", "Number"]
i = 0
rows = []
for name in element_names:
oneRow = [name,element_symbols[i],element_weights[i],element_numbers[i]]
rows.append(oneRow)
i += 1
data = system.dataset.toDataSet(headers, rows)
event.source.parent.getComponent('Table').data = data

6. Put all of that together and throw it on a button's actionPerformed event inside a window with a table on it and test away! It should be noted that this script will take a couple minutes to run since there is no function to get all of the weights, numbers or symbols in one method call. Be patient.

Next...