Continuous XML Parsing into Memory Tags

I haven’t tried this before, but I found this:

https://docs.inductiveautomation.com/display/DOC79/Parsing+XML+with+the+Etree+Library

I was able to use etree to parse out only the lowest <item> nodes values (since node names repeat in your devices returned xml doc). I had to change your tag reference to the multi-line string variable named ‘document’, but this should give the idea:

document = """
ADVANNET/1.0
Content-Length:955
Content-Type:text/xml

<?xml version="1.0" encoding="UTF-8"?>
<inventory>
	<type>inventory</type>
	<ts>1519314110000</ts>
	<status>OK</status>
	<msg-version>2.3.0</msg-version>
	<op>inventory</op>
	<data>
		<advanNetId>AdvanNet-instance-98:84:e3:98:91:a3--1</advanNetId>
		<deviceId>testing</deviceId>
		<inventory>
			<class>INVENTORY</class>
			<deviceId>testing</deviceId>
			<size>1</size>
			<items>
				<item>
					<class>READ_EVENT</class>
					<epc>e2002080801302511000b324</epc>
					<ts>1519314110571</ts>
					<deviceId>testing</deviceId>
					<data>
						<class>TAG_DATA</class>
						<hexepc>e2002080801302511000b324</hexepc>
						<props>
							<prop>TIME_STAMP:1519314110571,</prop>
							<prop>RSSI:-53,</prop>
							<prop>RF_PHASE:143,</prop>
							<prop>ANTENNA_PORT:1,</prop>
							<prop>MUX1:0,</prop>
							<prop>MUX2:0,</prop>
							<prop>FREQ:867341,</prop>
						</props>
					</data>
				</item>
			</items>
		</inventory>
	</data>
</inventory>
"""

import xml.etree.ElementTree as ET

declaration = '<?xml version="1.0" encoding="UTF-8"?>\n'
document = document.split(declaration)[1]
root = ET.fromstring(document)

for inventory in root.find('data/inventory/items/item'):
	for node in inventory.getiterator():
		if node.tag == 'deviceId':
			print node.tag, node.text
		elif node.tag == 'epc':
			print node.tag, node.text
		elif node.tag == 'ts':
			print node.tag, node.text

First we split() the XML document on the predefined declaration string, and select the second item (at index 1) to get rid of the declaration strings, instead of using replace() for each line. Then use the etree library to parse the string into an easily navigable document object, ‘root’. Then use root.find() to grab only the lowest-child item node, which is necessary since you have multiple definitions of ‘data’ and ‘inventory’. Of the items at that node, pull out the ones you need and do something with their text values.

In the above where I’m printing the node tag and text, you could easily just write back to predefined tags for those values. You should implement this in the OnValueChange event script of your XML tag.

When the XML data changes->parse out the new data->write to your new tags for deviceId, epc, and ts.

1 Like