Handling XML with Python
Why Should Network Engineers Care About XML?
In today’s world of APIs and structured data, XML (eXtensible Markup Language) may not be as hyped as JSON, but it’s still deeply embedded in network automation and device management. From NETCONF and RESTCONF to vendor-specific device outputs, XML is everywhere in the networking world.
Even though JSON is now dominant in modern APIs, XML still powers key infrastructure under the hood — especially in:
- NETCONF (RFC 6241) — relies heavily on XML for structured configuration and operational data.
- YANG models — data modeled in YANG often gets serialized as XML in NETCONF.
- SOAP APIs — older but still active APIs for NMS and OSS tools.
- CLI outputs from network devices — XML-formatted CLI outputs (e.g.,
show interfaces | display xmlon Juniper).
So, being fluent in XML parsing and manipulation is critical when building automation workflows or network audits.
XML 101: A Quick Primer
Here’s what XML looks like:
1
2
3
4
5
6
7
8
<interface>
<name>GigabitEthernet0/1</name>
<status>up</status>
<ip>
<address>192.168.1.1</address>
<netmask>255.255.255.0</netmask>
</ip>
</interface>
Unlike JSON, XML uses nested tags and supports attributes, like this:
1
2
3
<interface name="GigabitEthernet0/1" status="up">
<ip address="192.168.1.1" netmask="255.255.255.0"/>
</interface>
Key Concepts:
- Elements –
<tag>value</tag> - Attributes –
<tag attribute="value" /> - Namespaces – Used to avoid naming conflicts, especially in NETCONF.
- Well-formed vs. Valid XML – XML must follow structure rules (well-formed) and may optionally conform to a schema (valid).
Real-World XML in Networking
Here’s an example snippet from a NETCONF response:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<rpc-reply xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">
<data>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
<interface>
<name>GigabitEthernet0/0</name>
<enabled>true</enabled>
<ipv4>
<address>
<ip>192.0.2.1</ip>
<netmask>255.255.255.0</netmask>
</address>
</ipv4>
</interface>
</interfaces>
</data>
</rpc-reply>
Parsing XML with Python
Python has built-in and third-party libraries to handle XML. Let’s explore a few ways to parse and navigate XML as a network engineer.
1. xml.etree.ElementTree – Built-in & Simple
1
2
3
4
5
6
7
import xml.etree.ElementTree as ET
xml_data = """<interface><name>Gig0/1</name><status>up</status></interface>"""
root = ET.fromstring(xml_data)
print(root.find('name').text) # Output: Gig0/1
print(root.find('status').text) # Output: up
Use when the XML is simple and predictable. Limited namespace support.
2. Handling NETCONF XML with Namespaces
When using NETCONF, namespaces are always involved. You must specify them explicitly.
1
2
3
4
5
6
7
8
9
10
ns = {
'if': 'urn:ietf:params:xml:ns:yang:ietf-interfaces'
}
tree = ET.ElementTree(ET.fromstring(xml_with_namespace))
interfaces = tree.findall('.//if:interface', ns)
for intf in interfaces:
name = intf.find('if:name', ns).text
print(f"Interface: {name}")
Tip: Always map namespaces to prefixes and use those in your XPath queries.
3. lxml – More Power and XPath Support
1
2
3
4
5
from lxml import etree
tree = etree.fromstring(xml_data.encode())
names = tree.xpath('//interface/name/text()')
print(names)
Use
lxmlwhen dealing with complex XML, XPath queries, or schema validation.
Use Case: Extracting Interfaces from a NETCONF Response
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
from ncclient import manager
import xml.etree.ElementTree as ET
device = {
"host": "10.0.0.1",
"port": 830,
"username": "admin",
"password": "admin",
"hostkey_verify": False
}
with manager.connect(**device) as m:
filter = """
<filter>
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces"/>
</filter>
"""
response = m.get(filter)
xml_data = response.data_xml
ns = {'if': 'urn:ietf:params:xml:ns:yang:ietf-interfaces'}
root = ET.fromstring(xml_data)
for intf in root.findall('.//if:interface', ns):
name = intf.find('if:name', ns).text
print(f"Interface: {name}")
Bonus: Convert XML to JSON
Sometimes you need to convert XML to JSON for easier processing or integration.
1
2
3
4
5
6
7
import xmltodict
import json
xml_data = """<interface><name>Gig0/1</name><status>up</status></interface>"""
parsed = xmltodict.parse(xml_data)
json_data = json.dumps(parsed, indent=2)
print(json_data)
xmltodictis perfect for converting XML into Python dictionaries fast.