Wednesday, May 13, 2020

Parsing XML with namespaces in Python

Recently I had to parse an XML response from a webservice in Python for validation. I found that resources are limited when it comes to parsing XML files with namespaces in the internet. So, I thought of creating one by myself for reference.

Sample XML response:
<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <env:Header/>
   <env:Body>
      <ser:customerServiceResponse xmlns:ser="http://xml.abc.com/customer/services">
         <ser:customerReturn>
            <part: xmlns:part="http://xml.abc.com/customer/parts">
               <part:customerPart>
                  <n2:custName xsi:nil="true" xmlns:n2="http://xml.abc.com/parts"/>
                  <n3:compName xmlns:n3="http://xml.abc.com/parts">
                     <n3:bussName>testABC</n3:bussName>
                  </n3:compName>
                  <part:customerId>962977565</part:customerId>
            </part:customerPart>
         </ser:queryCustomerReturn>
      </ser:customerServiceResponse>
   </env:Body>
</env:Envelope>

Objective:
Extract the value of customerId from above xml

Code:
import xml.etree.ElementTree as ET
import requests

def test_xml_extract():
# define body and headers

#get the response
response = requests.post(url, data=body, timeout=60, headers=headers)

#get the lement tree as root
root = ET.fromstring(response.content)

#define namespaces as a dict
ns = {'env': 'http://schemas.xmlsoap.org/soap/envelope',
      'ser': 'http://xml.abc.com/customer/services',
      'part': 'http://xml.abc.com/customer/parts'}

#extracting the element
cust_id = root.find('.//part:customerPart/part:customerId', ns).text
print("CustId : {}".format(cust_id))

In the above example we used a xpath style search and retriving the text from the element.



No comments:

Post a Comment