In this tutorial, you will learn how to decode and parse a large SOAP XML response with Python and regular expression, essentially the goal here was to build a Python function to get rid of manually decoding SOAP XML response over and over again.
The Python code I’m about to explain and show you was developed as a part of refund payment integration done in Python and Django.
We’re going to take a look at an encoded SOAP XML response stdout saved in a text file.
I saved this SOAP response output when I was in a process of developing a payment integration feature for a local bank here in Riga, Latvia, along the way I realized it’s going to be a great learning experience for anyone else who’s going to search for a similar solution on Google.
I’ve discussed similar text file parsing in Python situations before here on the blog, but the difference here is that this one is way more complicated and involves a bit more decoding and text manipulation as well as extensive knowledge on regex pattern matching.
Definitely a good Python regular expression practice, even for advanced Python developers.
Currently, I’m working as a Python Django backend developer (Roberts Greibers) for a local company here in Riga, Latvia – building a white-label payment gateway platform, you can find more about my experience on my Linkedin profile
Give me a follow on Linkedin or send me a DM if you have any questions.
One of the recent payment integration flows I needed to develop was for a refund payment. Refund payments were supposed to work for multiple banks through one gateway system for this particular client and brand.
The whole refund payment flow is way more complicated and would take me weeks to write up and explain here on the blog so I’m gonna share a small portion of what actually was very interesting to work on – parsing decoded SOAP XML response with regular expression in Python.
I go deeper explaining features you can develop for your Python and Django portfolio if you’re working personally with me in one on one Zoom calls (click here to see an example of a LIVE Zoom call). I personally will guide you through the development of each feature and answer all your questions along the way.
This is what we’re working on with my most successful mentoring clients.
So if the above sounds interesting, let’s get started!
SOAP XML Response Example
Before we get into the solution, let me explain to you what exactly is the problem here and why you would need to write a parsing function for it.
Payment Refund Flow Explained
- Initiate payment refund through payment gateway (Gateway CLI is written in Java – use Python subprocess package to run the file)
- After Gateway CLI payment initiation request, Gateway CLI has a built-in while loop to empty a response queue and receive all responses, not just one – meaning if there are multiple responses in a queue on the Gateway side (bank system side), we will receive multiple responses.
- Later in the flow, each response must be matched with a PostgreSQL database object. (not included in this tutorial for the sake of simplicity)
- Because of the above situation, I needed to write a Python parsing code that would expect to receive and decode multiple SOAP XML responses.
- After parsing request responses I did match each response with an object in a database, but as I mentioned before – I’m going to skip this part for the tutorial here as it involves way more details about the whole refund payment flow.
The above points should be enough for you to understand the context and what we’re dealing with.
SOAP XML Scheme Response Example
This is a SOAP XML scheme response example for a single refund payment initiation – it’s already decoded, meaning, this is the end result you want to extract from the whole SOAP XML response.
The XML response below looks good, human-readable, and fairly easy to understand for anyone.
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03">
<CstmrPmtStsRpt>
<GrpHdr>
<MsgId>GW00000032980679</MsgId>
<CreDtTm>2022-02-11T00:00:00</CreDtTm>
<InitgPty>
<Id>
<OrgId>
<BICOrBEI>PARXLV22</BICOrBEI>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<OrgnlGrpInfAndSts>
<OrgnlMsgId>9G5NSPSQHQ8HGARS</OrgnlMsgId>
<OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId>
<GrpSts>ACSP</GrpSts>
</OrgnlGrpInfAndSts>
<OrgnlPmtInfAndSts>
<OrgnlPmtInfId>17d273331478416d9fbec2477f55b00e</OrgnlPmtInfId>
<TxInfAndSts>
<OrgnlInstrId>ROMCMGCMV5GSAV</OrgnlInstrId>
<OrgnlEndToEndId>17d273331478416d9fbec2477f55b00e</OrgnlEndToEndId>
<TxSts>ACSP</TxSts>
</TxInfAndSts>
</OrgnlPmtInfAndSts>
</CstmrPmtStsRpt>
</Document>
Refund Payment Gateway CLI Stdout Example
When a refund payment initiation request is executed through Gateway CLI, the following output is generated from the CLI.
This is just a part of it for you to get the idea.
Feb 11, 2022 4:13:31 PM storm.webservice.cli.B4BGateTesterCliAppReq readOrCreateAppReq
INFO: Prepare and sign APPREQ message container
Feb 11, 2022 4:13:31 PM storm.webservice.cli.B4BGateTesterCliAppReq processData
INFO: Send message [OUT-rb4kjoq11482oeh1hhuvtuggbs] to [https://astra.citadele.lv/gate/B4BGateway]
Feb 11, 2022 4:13:32 PM [com.sun.xml.ws.policy.parser.PolicyConfigParser] parse
INFO: WSP5018: Loaded WSIT configuration from file: jar:file:/Users/robertsgreibers/projects/spell-klix-fix/ext/citadele_gateway/dist/gate-tester-cli.jar!/META-INF/wsit-client.xml.
---[HTTP request - https://astra.citadele.lv/gate/B4BGateway]---
Accept: text/xml, multipart/related
Content-Type: text/xml; charset=utf-8
SOAPAction: "http://b4b.webservice.storm.citadele.lv/B4BGateway/postRequest"
User-Agent: Metro/2.3 (tags/2.3-7528; 2013-04-29T19:34:10+0000) JAXWS-RI/2.2.8 JAXWS/2.2 svn-revision#unknown
<?xml version='1.0' encoding='UTF-8'?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#"><S:Header><To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5004">https://astra.citadele.lv/gate/B4BGateway</To><Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1" wsu:Id="_5006">http://b4b.webservice.storm.citadele.lv/B4BGateway/postRequest</Action><ReplyTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5003">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo><FaultTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</FaultTo><MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5002">uuid:b9ad1502-1a70-4e70-9762-2e1cfa94013e</MessageID><wsse:Security S:mustUnderstand="1"><wsu:Timestamp xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" wsu:Id="_3"><wsu:Created>2022-02-11T14:13:32Z</wsu:Created><wsu:Expires>2022-02-11T14:18:32Z</wsu:Expires></wsu:Timestamp><wsse:BinarySecurityToken xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" wsu:Id="uuid_020a8275-e036-4e5d-8903-0c0bb214755a">MIIFWzCCA0OgAwIBAgIEXrd9UjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJMVjEPMA0GA1UECBMGTGF0dmlhMQ0wCwYDVQQHEwRSaWdhMRIwEAYDVQQKEwlTSUEgU3BlbGwxCzAJBgNVBAsTAklUMQ4wDAYDVQQDEwVTcGVsbDAeFw0yMTEyMTAwOTQ0NTRaFw0yMzExMzAwOTQ0NTRaMF4xCzAJBgNVBAYTAkxWMQ8wDQYDVQQIEwZMYXR2aWExDTALBgNVBAcTBFJpZ2ExEjAQBgNVBAoTCVNJQSBTcGVsbDELMAkGA1UECxMCSVQxDjAMBgNVBAMTBVNwZWxsMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAjIb7rPzKeBkeuymTcwO+6X9LwZ40ML6LhRrtW1hJZeW08IKevWCV6LV6A0rQ9u7yLNVlMtcmi3HxMc+azi8xP/ZBjD6XBH5rkV8927ayLEJvGs1/eTmIRg0kCkm00A1MlzTstAh9iarv1jcVY7goFLEDO8aGb73EMLARqG75AG5OOcKl+ggS8lCkhsBQcls8vwrsUVF8A3Eq8uBbfark6P8F0gWCi5ivQxJ7uV7phemtOoVC8o8gi1IhZaVaz2didW7aScjJwFPDxSqNE9yilqbpk+2dAJbyeFnpGlywY3WrRu2kcgq+iFW3l+k2PCOmR71z9iUtodmj29zAgXG7bdyEuXortf+vmGxj5F2aTYqhwvrFOhnpxi99QHHA9Gp/EEDSH9WDwfhBoNHDw1A0/ne1+Awf+/JDj7HQieqIaruWjXzHf1f/QeZPePAuQie36zPMM634ryjfLN+H+UKWWtnEbI9IGDE3XDD75zfp2uvRzstdOIi+gPBKhE3WIiG2NKrrRpOe9p/TgEpm3/fOuqesgXP+7fvisMMHul43p9mgt6aVVUEXJ9thRCjrc9++P4PF4okrr4Elx/G/JZ2QZdNZD3oz9ORBggH2ALpzsYTza7n1IhFrHmFad6IsoKvDOG9Wp47YJZ58o5J+ieMohXTcovVwwzvTyW6xeH6EIyMCAwEAAaMhMB8wHQYDVR0OBBYEFIwatrKmBy6cMz+OhqZ69HQY+et/MA0GCSqGSIb3DQEBCwUAA4ICAQAI+oAMpGBT6gUIl/MMKdugvAnBgTen/lkjFrcCDyPQzrp5kGaKdSzXc7IvJOEDZsjzeEu7idK+4YgyA2tU/EOIsuUMNd8ZD/WQ10grXorEa1ZqgPHOwgEpbWr3Ln2ShoauqtgbNoD2OeEOtgacXFGCuE07fnuszCrB1eHC2Noay+7nw/yw5JZc+b0JNy8PhjE3G2SopnRUCMGSa4AtrA0/J8129Fkuxzr5VkQJWPVgVyD9SZTlC0jcZEq87byEVh8qL2ufUNn96fl2X6g77BnJySuZFOKtqaeckClHTjjI71ntg1Q3tIbseFk4qlum/ZdDHYLPc8E/D7/kMLQSWIiiNpccyGYBL7E90gKXY/+T82+8LdLxdiBqiD3Pv3zL46fp+dxKEr0XTSb2UfdiFDfVCjz8+S91f/DrvxdLanjGl6khm3SKE5C/v56WcfbnNbwxNOZI8GArvEQRQW0o3mH8E673x/OMjyQlLJ2A+RT927z2nDBlvhukus9CTLNz/rmNsf5ToMK6oXxnsFmZdddaVmt7ZcfcroQMsk+ocPg3OeDay2T6HJPQqkswWduGypTM4cFdQBQdA3dVud8WEUsUBOfmd65CmjTo9bftG3a7YSFRGEoL7ivfd0/TE+R+j9JPBYAne0Vs3hBpaQg/7LIoLZ95VflJxXlr5wGKnY3evA==</wsse:BinarySecurityToken><ds:Signature xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" Id="_1"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsse S"/></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#_5002"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>jn9/pNlVYlCBBc+d02/zQ4Chz6B9dRr74prupiH6ggA=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5003"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>BLilqqtfNb5YsgCr4//VCHWRiNGtWRSjWYMY5G6CaQk=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5004"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>8arAeAZRAtmd5SZgvv10oMFU2K+ENVnz7km1fJh1Q28=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5005"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>fAzBFG8TCs1Az+T7t1Xk56d0Tor6o2HKIomH/ZwZFF4=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5006"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>KQ2WA+qmPi88bA9LaegZdG561UtJvqjPWpwv66ik0tc=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5007"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>srh1Ke8vq9GAlrU2TneeEdlI+PzZjngEoyfMSSbvj4Y=</ds:DigestValue></ds:Reference><ds:Reference URI="#_3"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsu wsse S"/></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>DCLJMKQcWq9EfxJ/En8LtSe1zDxjSe9j3iJ30gS3D+I=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>I94BmjgD6WJmujKthMk/vUjSLpa9uUTmkqDyHrQ0WumWeBw7t8k7cFtK39d92nU+q2P9e7ILRXOYA0iZCQcx9zmLVTgzal3w9E4FJOParXGm+rSqiapRIEgCi/Q+49Pe3skLGKq3Z1dHcFQPGHvM3eqREFUiTn9GVgQi/fz7FCxXQDIC5zMw7gAXTqWQgAcV0UOASy64Htb1DtjMpER3u/y8gnmic356P9ZtIcLDQPC/VUbB6j/MivSt5bkEGUdbcXKyKkef2e9zOrbdqKCfmnWaWBDsdKp5FybAo91ijnFbJWWO3Q4+5MLI0QtcJZlwDcBYx7zlOwshZooCL5s/h1FyCaM76P77wEcIcn/DoznO6X0yh9a+H3GJEU2eG1bTN4EtqOkBiaPzSLR22turU6lmyU6edZK8G1dZIvz27TvAWpUZ4a6j5GKZ950A7uLPUwNbEO/Imfmt7PL0at29UUepXtM/yuG/cLx+/YL0AZHorwLVSp8chE1U+DdS0ROcLq97KMh4mJEPNy1FUw9PjprNwYkS6ChDPRvZ+pSKBC/SUSceE/xH/KySw2w/wUo0c5KsXdbmZXmVEGkRccU25LBM7s+a00B4LlasweJYNg2CSIfchlhwPM09ap05xTaTVx7WaxVIugP7TDD/io0C1rr5Eh6eocZFUK/2RyQ2LcY=</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference><wsse:Reference URI="#uuid_020a8275-e036-4e5d-8903-0c0bb214755a" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3"/></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></S:Header><S:Body wsu:Id="_5007"><ns2:post xmlns:ns2="http://b4b.webservice.storm.citadele.lv"><data><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PENCLkI0Qi5BUFAuUkVRIHhtbG5zPSJ1cm46Q0JCNEJBUFBSRVE6eHNkOkNCLkI0Qi5BUFAuUkVRIiB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVRPC9UeXBlPjxDb250ZW50IElkPSJhNTNlOThlNC0wMTk3LTQ1MTMtYmU2ZC00OTgzNmU0MDZhYWEiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K1BFTkNMa0kwUWk1UVNVNUhMbEpGVVNCNGJXeHVjejBpZFhKdU9rTkNRalJDVUVsT1IxSkZVVHA0YzJRNlEwSXVRalJDTGxCSlRrY3VVa1ZSSWo0S0NUeFdZV3gxWlQ1UWFXNW5QQzlXWVd4MVpUNEtQQzlEUWk1Q05FSXVVRWxPUnk1U1JWRSs8L0NvbnRlbnQ+PFNpZ25hdHVyZXM+PFNpZ25hdHVyZSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFNpZ25lZEluZm8+PENhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxSZWZlcmVuY2UgVVJJPSIjYTUzZTk4ZTQtMDE5Ny00NTEzLWJlNmQtNDk4MzZlNDA2YWFhIj48RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8+PERpZ2VzdFZhbHVlPnNOaG94ZjZBRUxmQjJTczZHQ3lKUkl2SEZ4TnZheFhTSEtXSGp6ZFVrVE09PC9EaWdlc3RWYWx1ZT48L1JlZmVyZW5jZT48L1NpZ25lZEluZm8+PFNpZ25hdHVyZVZhbHVlPllUdWtFYUxxcllKQmRZZWVMdTVuNlJ1NktKdGJQb3dMVXI1MFNqZXV1SWcxN0VGWTFjcVpuUTQzSkhibEE3M3FTbFZ2OW11VjJnQ3gmIzEzOwo5Ulh4SEdSYnVFd1pVNGxXMDRzdUdvOFVMOUxrMm9nMXA1b3pKYVY1czZra1l4TldiQXhmUlVTZHpadXdHNE1OeDluM3NudzhKY2pjJiMxMzsKVVo2Q3Q3MzF4YzdQZ1A0TTBJUnkxZHd6MjNBeldqOXE3U1BPTzI3WHVOK2R1Snk5aVVxMlpDQ1FhR3ZBRGxoNkllYjd5amZJRkk3VSYjMTM7ClYzeHdHTXZIYm1GTVVJQ2taSUFZcUFBTVMyUmh1Wmt1WEVxcm9oRWZ3U1djOVp1RjBDR3dWbjFEaEV0Z3N1SmQzampPNXl5b2dnZismIzEzOwp3L2VKWnNDbmJBbUZ5VzQyd3VhdDY1VFYweVpDV0FQbkpRNjVSSWdBenlleXJwZ05yZmsrNlloUHJpcHpnMkJUaVE4WGxGQUQxQUovJiMxMzsKZDVuOVF3YUQyMmFsZ2pTOGJDMm11MWxSWndXM0l6MVJjMUZ0WjNQMGYrcmN6RmcxUVZ4NmJTOHNPUGdzWnhqWThOam9PRVJlWXRxLyYjMTM7Ck53eCs3ZVI2cE8zNnZxbmR6QnJpeGExdWxNRndHZEhwWHNUNVFhZGZFSGVhTmpKd3dxa3JGRDRvSkJuZGpnSHFGQnh3MzNVaUtzdWsmIzEzOwo2Tm9NUkh0dmcyN0N1UkJtVEdLUTNYZEc5dHpFSkZZUzJmdlJWWkhhczJUdy9WRUk3Tm5YOW4vVlF4eG9CMHdpbU9WTVNkbnVJOWx0JiMxMzsKeUxjRW1LQ2piU1M1VkRQSmp0RlpKSTIvZjdkTGNKdTEvMkZzdVE1d3RTdXN4TzRTaXdseWtUQ1pYdnBVeEJVS3l6b1lXZ0JIN2hBPTwvU2lnbmF0dXJlVmFsdWU+PEtleUluZm8+PFg1MDlEYXRhPjxYNTA5U3ViamVjdE5hbWU+Q049U3BlbGwsT1U9SVQsTz1TSUEgU3BlbGwsTD1SaWdhLFNUPUxhdHZpYSxDPUxWPC9YNTA5U3ViamVjdE5hbWU+PFg1MDlDZXJ0aWZpY2F0ZT5NSUlGV3pDQ0EwT2dBd0lCQWdJRVhyZDlVakFOQmdrcWhraUc5dzBCQVFzRkFEQmVNUXN3Q1FZRFZRUUdFd0pNVmpFUE1BMEdBMVVFJiMxMzsKQ0JNR1RHRjBkbWxoTVEwd0N3WURWUVFIRXdSU2FXZGhNUkl3RUFZRFZRUUtFd2xUU1VFZ1UzQmxiR3d4Q3pBSkJnTlZCQXNUQWtsVSYjMTM7Ck1RNHdEQVlEVlFRREV3VlRjR1ZzYkRBZUZ3MHlNVEV5TVRBd09UUTBOVFJhRncweU16RXhNekF3T1RRME5UUmFNRjR4Q3pBSkJnTlYmIzEzOwpCQVlUQWt4V01ROHdEUVlEVlFRSUV3Wk1ZWFIyYVdFeERUQUxCZ05WQkFjVEJGSnBaMkV4RWpBUUJnTlZCQW9UQ1ZOSlFTQlRjR1ZzJiMxMzsKYkRFTE1Ba0dBMVVFQ3hNQ1NWUXhEakFNQmdOVkJBTVRCVk53Wld4c01JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQyYjMTM7CkNnS0NBZ0VBakliN3JQektlQmtldXltVGN3Tys2WDlMd1o0ME1MNkxoUnJ0VzFoSlplVzA4SUtldldDVjZMVjZBMHJROXU3eUxOVmwmIzEzOwpNdGNtaTNIeE1jK2F6aTh4UC9aQmpENlhCSDVya1Y4OTI3YXlMRUp2R3MxL2VUbUlSZzBrQ2ttMDBBMU1selRzdEFoOWlhcnYxamNWJiMxMzsKWTdnb0ZMRURPOGFHYjczRU1MQVJxRzc1QUc1T09jS2wrZ2dTOGxDa2hzQlFjbHM4dndyc1VWRjhBM0VxOHVCYmZhcms2UDhGMGdXQyYjMTM7Cmk1aXZReEo3dVY3cGhlbXRPb1ZDOG84Z2kxSWhaYVZhejJkaWRXN2FTY2pKd0ZQRHhTcU5FOXlpbHFicGsrMmRBSmJ5ZUZucEdseXcmIzEzOwpZM1dyUnUya2NncStpRlczbCtrMlBDT21SNzF6OWlVdG9kbWoyOXpBZ1hHN2JkeUV1WG9ydGYrdm1HeGo1RjJhVFlxaHd2ckZPaG5wJiMxMzsKeGk5OVFISEE5R3AvRUVEU0g5V0R3ZmhCb05IRHcxQTAvbmUxK0F3ZisvSkRqN0hRaWVxSWFydVdqWHpIZjFmL1FlWlBlUEF1UWllMyYjMTM7CjZ6UE1NNjM0cnlqZkxOK0grVUtXV3RuRWJJOUlHREUzWERENzV6ZnAydXZSenN0ZE9JaStnUEJLaEUzV0lpRzJOS3JyUnBPZTlwL1QmIzEzOwpnRXBtMy9mT3VxZXNnWFArN2Z2aXNNTUh1bDQzcDltZ3Q2YVZWVUVYSjl0aFJDanJjOSsrUDRQRjRva3JyNEVseC9HL0paMlFaZE5aJiMxMzsKRDNvejlPUkJnZ0gyQUxwenNZVHphN24xSWhGckhtRmFkNklzb0t2RE9HOVdwNDdZSlo1OG81SitpZU1vaFhUY292Vnd3enZUeVc2eCYjMTM7CmVINkVJeU1DQXdFQUFhTWhNQjh3SFFZRFZSME9CQllFRkl3YXRyS21CeTZjTXorT2hxWjY5SFFZK2V0L01BMEdDU3FHU0liM0RRRUImIzEzOwpDd1VBQTRJQ0FRQUkrb0FNcEdCVDZnVUlsL01NS2R1Z3ZBbkJnVGVuL2xrakZyY0NEeVBRenJwNWtHYUtkU3pYYzdJdkpPRURac2p6JiMxMzsKZUV1N2lkSys0WWd5QTJ0VS9FT0lzdVVNTmQ4WkQvV1ExMGdyWG9yRWExWnFnUEhPd2dFcGJXcjNMbjJTaG9hdXF0Z2JOb0QyT2VFTyYjMTM7CnRnYWNYRkdDdUUwN2ZudXN6Q3JCMWVIQzJOb2F5Kzdudy95dzVKWmMrYjBKTnk4UGhqRTNHMlNvcG5SVUNNR1NhNEF0ckEwL0o4MTImIzEzOwo5Rmt1eHpyNVZrUUpXUFZnVnlEOVNaVGxDMGpjWkVxODdieUVWaDhxTDJ1ZlVObjk2ZmwyWDZnNzdCbkp5U3VaRk9LdHFhZWNrQ2xIJiMxMzsKVGpqSTcxbnRnMVEzdElic2VGazRxbHVtL1pkREhZTFBjOEUvRDcva01MUVNXSWlpTnBjY3lHWUJMN0U5MGdLWFkvK1Q4Mis4TGRMeCYjMTM7CmRpQnFpRDNQdjN6TDQ2ZnArZHhLRXIwWFRTYjJVZmRpRkRmVkNqejgrUzkxZi9EcnZ4ZExhbmpHbDZraG0zU0tFNUMvdjU2V2NmYm4mIzEzOwpOYnd4Tk9aSThHQXJ2RVFSUVcwbzNtSDhFNjczeC9PTWp5UWxMSjJBK1JUOTI3ejJuREJsdmh1a3VzOUNUTE56L3JtTnNmNVRvTUs2JiMxMzsKb1h4bnNGbVpkZGRhVm10N1pjZmNyb1FNc2srb2NQZzNPZURheTJUNkhKUFFxa3N3V2R1R3lwVE00Y0ZkUUJRZEEzZFZ1ZDhXRVVzVSYjMTM7CkJPZm1kNjVDbWpUbzliZnRHM2E3WVNGUkdFb0w3aXZmZDAvVEUrUitqOUpQQllBbmUwVnMzaEJwYVFnLzdMSW9MWjk1VmZsSnhYbHImIzEzOwo1d0dLblkzZXZBPT08L1g1MDlDZXJ0aWZpY2F0ZT48L1g1MDlEYXRhPjwvS2V5SW5mbz48L1NpZ25hdHVyZT48L1NpZ25hdHVyZXM+PC9DQi5CNEIuQVBQLlJFUT4=</data><header><msgRef>OUT-rb4kjoq11482oeh1hhuvtuggbs</msgRef><msgType>APPREQ</msgType></header></data></ns2:post></S:Body></S:Envelope>--------------------
---[HTTP response - https://astra.citadele.lv/gate/B4BGateway - 200]---
null: HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/xml;charset=utf-8
Date: Fri, 11 Feb 2022 14:13:33 GMT
Keep-Alive: timeout=15, max=100
Transfer-Encoding: chunked
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#"><S:Header><Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1" wsu:Id="_5004">http://b4b.webservice.storm.citadele.lv/B4BGateway/postResponse</Action><MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5002">uuid:b3f0c0c5-c8a4-4ba1-952c-5184d7088dd8</MessageID><RelatesTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">uuid:b9ad1502-1a70-4e70-9762-2e1cfa94013e</RelatesTo><To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5003">http://www.w3.org/2005/08/addressing/anonymous</To><wsse:Security S:mustUnderstand="1"><wsu:Timestamp xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns="" wsu:Id="_3"><wsu:Created>2022-02-11T14:13:33Z</wsu:Created><wsu:Expires>2022-02-11T14:18:33Z</wsu:Expires></wsu:Timestamp><ds:Signature xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns="" Id="_1"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsse S"></exc14n:InclusiveNamespaces></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></ds:SignatureMethod><ds:Reference URI="#_5002"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>lYbEDC2VLuLY/yCwbKjH4Xh8LsdfTUr/R2980czojH0=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5003"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>3sWNXSUOXzbABMJQW6+gVgUSYpuYCzQuufWOcJetVHc=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5004"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>w3UcEvZXIFutTmCLIh6XUZ4qVoR5baX86H9CbsRWJW4=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5005"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>6tcYUBBUeZ7rwix6JsMvj6jNBidQLt2be01KECwQcqs=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5006"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>eKR23gckJRbS8XLbQxTFPYazrcf8vHBK3uQOY5oCfEA=</ds:DigestValue></ds:Reference><ds:Reference URI="#_3"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsu wsse S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>7j5Uc4cafAAssXWfF0+eBLZUi0dLmLKujCKQsuti/Rc=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>SWhcEZd9aH+K6xVfTWmSc2/HGtta7KBEsuYvxHBt9HQibn7cCVT+uUdUnG6GMOFtiad68s6q6MZEVDUuQUNWsF7RY/Z5ntmznfSb3bJj8At11PqHGnaYofNU0lURn4RGAx2PYTY2v/e0ICB2Zv2iKx1cF6qwMRVrc6OvSp73VswMda9oevyrx5rNtPI9Wkjq30cb9VIO+83/gF/zlVCC9SVHYxEfEaHe6Tl5Y4prNAZsf1AnpJLDntKdfl976zSsvt+7xoo2mB7wP8EaAA3G4fgb7AqNFYb3xE/f+GsCUJh0F09d+/f7Xq2NeFHv4lb8eHa8CZGPPL3UyHwWAC+hqenn0KaeC6D9WF0sdFL5Ob7+eHOqBReh639U1m7NkTAi2V1wb8nZg4Ptplxg1Y54qMR8mZSPb1Si3ajeisrryJqcxkviIHjNQXS7FtkhxkgVJryhngn2L1p2QXsW3e5c7I+Lu65NcMm8x1Y1586oC6071t7am3jrGhUKRXvubyG4a46n4IpGn7WIjAgN7hWIS2pDzPTUcohU5kwFIclM4fJttEu6mYdleGuV8uIlHY0mVqjMXsR+M07U9KFP+1kejWnBC5+Zr87A3pCO/EfnhkUdLtdmp5T8P3fOOtCq7sbtybiQimyzloqwbXb1im83iTFJYUHx/MB87y2cbyO1cFg=</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=Gateway Test Astra, OU=IT, O=Citadele Banka AS, L=Riga, ST=Latvia, C=LV</ds:X509IssuerName><ds:X509SerialNumber>421118815</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></S:Header><S:Body wsu:Id="_5006"><ns2:postResponse xmlns:ns2="http://b4b.webservice.storm.citadele.lv"></ns2:postResponse></S:Body></S:Envelope>--------------------
If you want to test the following Python SOAP XML response parsing script with a similar stdout, you have to download example stdout here:
Analyze Refund Payment Gateway CLI Stdout
When it comes to a situation where you have to analyze a large output of any kind it’s better to separate it into multiple parts to understand what are you actually looking for.
The first GOLDEN RULE in programming – don’t write code before you completely understand the situation.
In order to understand what exactly is the problem, I copied one of the responses from the stdout_example.txt file you can download above.
Once you have one of the responses, to make it more readable format the whole SOAP XML however you can – I’ll use some XML formatting side from Google search.
Just to understand the process of decoding a SOAP response you have to through it manually.
Use This SOAP XML Response For Analyzation
I’d always recommend understanding each step before writing any code. In order for you to follow the next steps you need to use the response from the code block below (almost the same as in the screenshot above, but this one will actually have a proper XML response after decoding)
---[HTTP response - https://astra.citadele.lv/gate/B4BGateway - 200]---
null: HTTP/1.1 200 OK
Connection: Keep-Alive
Content-Type: text/xml;charset=utf-8
Date: Fri, 11 Feb 2022 14:13:42 GMT
Keep-Alive: timeout=15, max=95
Transfer-Encoding: chunked
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns:exc14n="http://www.w3.org/2001/10/xml-exc-c14n#"><S:Header><Action xmlns="http://www.w3.org/2005/08/addressing" xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" S:mustUnderstand="1" wsu:Id="_5004">http://b4b.webservice.storm.citadele.lv/B4BGateway/getResponse</Action><MessageID xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5002">uuid:39b85a4c-153d-423e-9796-895b17b1dc66</MessageID><RelatesTo xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5005">uuid:d0fcebc5-427c-44ee-8ab5-18b9ef5259f6</RelatesTo><To xmlns="http://www.w3.org/2005/08/addressing" wsu:Id="_5003">http://www.w3.org/2005/08/addressing/anonymous</To><wsse:Security S:mustUnderstand="1"><wsu:Timestamp xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns="" wsu:Id="_3"><wsu:Created>2022-02-11T14:13:42Z</wsu:Created><wsu:Expires>2022-02-11T14:18:42Z</wsu:Expires></wsu:Timestamp><ds:Signature xmlns:ns16="http://docs.oasis-open.org/ws-sx/ws-secureconversation/200512" xmlns:ns15="http://www.w3.org/2003/05/soap-envelope" xmlns="" Id="_1"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsse S"></exc14n:InclusiveNamespaces></ds:CanonicalizationMethod><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"></ds:SignatureMethod><ds:Reference URI="#_5002"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>JT8OJbidIRnUF2S9XUW7gcLnwHzy+lW+72T4kt4h1Ss=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5003"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>3sWNXSUOXzbABMJQW6+gVgUSYpuYCzQuufWOcJetVHc=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5004"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>P4UwgIO7BhHBcOM6KGxcQxWZfvUBkr6hdITdytHg+Js=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5005"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>fs51tpnHv+/E5CF5zO5IWsDAFDiYhcAavrECs5s7Hlw=</ds:DigestValue></ds:Reference><ds:Reference URI="#_5006"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>/BPeQrs/l2DDHW9/DKz+/bOe4x71ZrkrDJNwR7MMsYc=</ds:DigestValue></ds:Reference><ds:Reference URI="#_3"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"><exc14n:InclusiveNamespaces PrefixList="wsu wsse S"></exc14n:InclusiveNamespaces></ds:Transform></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"></ds:DigestMethod><ds:DigestValue>Uvlgd7kIYyM/1K468+wRoO0otAE/nZmLfIGBRAWwQ/A=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>XcShltsdH/KoQScGGQl/M3jKgpk+oNGFYH6gkq7O6a9jB66BXOLzY2apUB3u6b+9LKZ4ICqa9nvCt3tK+yN3t0RHL3OEsYS5qKVIhO/ijDOw9vYWuqiIStVBQVouBmajvxxX/zmZOXfAfH1uWCYWQhn+MR3aItjZDsg1ooOp7u0MRl/6LTx6RD+uK83JSfja7X+sr48ZqSEmLOFF0mWle9kX40DyEKXgG/z4VflsjxgbwZj1uvaIMu5w4Oh6DuwDsU0SMATjFwxNZyrdym3cGNRhjQAXqU1u4ex6siZgnIoETdzX0V4XERd3X6GJHwU9GT/CTPW28u/pPvKABqQCSqEWp6nRf76d6WDoBDx5Sx0D0KQn/lG4rN7INYdFP0VOilcsiVFJyleILaJUa6lEYBUizxnPvsUFHPlzdBAu4DeaG6Cxztll++0Djjbgww+Zk8pDb+jNk2Kfs8noqUKyAYsNyf2UsbXxtt5JkgZSojk7k32wlF+wNJSMccBnge32TuwID9K3kkz52EmxgBL0i2Vu69jWV65PWiFO37vW+kOET6L2H9HzXYXm5zgt93Rh7RWzplLhXseKhrD70IIq2boCYx1Nk9veyHpF0VFc5SRwl/Fc9Ht1gYJ4vG9OefSAkUAIe+aB3TTo8uO+OhDZ1Z3RRnydrSKAd5vS5jgZr8o=</ds:SignatureValue><ds:KeyInfo><wsse:SecurityTokenReference><ds:X509Data><ds:X509IssuerSerial><ds:X509IssuerName>CN=Gateway Test Astra, OU=IT, O=Citadele Banka AS, L=Riga, ST=Latvia, C=LV</ds:X509IssuerName><ds:X509SerialNumber>421118815</ds:X509SerialNumber></ds:X509IssuerSerial></ds:X509Data></wsse:SecurityTokenReference></ds:KeyInfo></ds:Signature></wsse:Security></S:Header><S:Body wsu:Id="_5006"><ns2:getResponse xmlns:ns2="http://b4b.webservice.storm.citadele.lv"><return><data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI0OTgzYTE0MS1mN2JlLTQzN2QtOGYwMS03NjE1M2RiMTYxMzYiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU56VTVOamc4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ERXRNalJVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStSMDh6TUZCVFRFYzROa280Vms1R05Ud3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5EVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpGbE56STJZamcyTWpOak1qUTBOVFJpWVRjMVl6QTNOelprTXpZNVkyWmlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrZFRNVGhPT0U0MVZFSlNNMDh3UEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhaVGN5Tm1JNE5qSXpZekkwTkRVMFltRTNOV013TnpjMlpETTJPV05tWWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTBOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==</data><header><msgRef>GW00000032975969</msgRef><msgType>APPREQ</msgType><origMsgRef>OUT-h1j2dq51409ojgb42998l4gc9e</origMsgRef></header></return></ns2:getResponse></S:Body></S:Envelope>--------------------
Copy and paste the above response XML into XML formatted to be able to easily find the necessary XML tags.
Pretty Format SOAP XML Response
Pay attention to the end of the response, it has “———-” dashes that need to be removed in order for you to be able to format the XML properly – delete these dashes and click on the blue FORMAT XML button (see the screenshot below)
After formatting, find <data>...</data>
tag and copy the content of it. The content of the XML <data>...</data>
tag is encoded with base64 and needs to be decoded to find the actual response.
Use Base64 Decoding For A SOAP XML Tag
Okay, so the next step is to decode the content of <data>...</data>
tag above. With a quick Google search you’ll find a lot of websites for base64 decoding, for the steps here I’ll use this one.
So, as you can see in the screenshot above I’ve pasted the content of the XML <data>...</data>
tag and the decoded result should be very similar to the screenshot below.
And here’s the important part, once you decode SOAP XML <data>...</data>
tag for the first time, the result is another XML scheme with a base64 encoded <Content>...</Content>
tag.

Copy the content of SOAP XML <Content>...</Content>
tag and paste it inside another base64 decoder, you can use the same base64 decoder website in another browser tab.
And finally, we have a fully decoded version of a SOAP response. Well quite some steps to go through just to see the results of the SOAP response, right? The next goal is to write Python code to do all the above steps automatically.
Here’s the pretty formatted and fully decoded SOAP XML response:
<?xml version="1.0" encoding="UTF-8"?>
<Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03">
<CstmrPmtStsRpt>
<GrpHdr>
<MsgId>GW00000032975968</MsgId>
<CreDtTm>2022-01-24T00:00:00</CreDtTm>
<InitgPty>
<Id>
<OrgId>
<BICOrBEI>PARXLV22</BICOrBEI>
</OrgId>
</Id>
</InitgPty>
</GrpHdr>
<OrgnlGrpInfAndSts>
<OrgnlMsgId>GO30PSLG86J8VNF5</OrgnlMsgId>
<OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId>
<GrpSts>ACCP</GrpSts>
</OrgnlGrpInfAndSts>
<OrgnlPmtInfAndSts>
<OrgnlPmtInfId>1e726b8623c24454ba75c0776d369cfb</OrgnlPmtInfId>
<TxInfAndSts>
<OrgnlInstrId>GS18N8N5TBR3O0</OrgnlInstrId>
<OrgnlEndToEndId>1e726b8623c24454ba75c0776d369cfb</OrgnlEndToEndId>
<TxSts>ACCP</TxSts>
</TxInfAndSts>
</OrgnlPmtInfAndSts>
</CstmrPmtStsRpt>
</Document>
Decode SOAP XML With Python And Regex
Alright, now that you have a better idea of how the SOAP XML response can be fully decoded manually, you’d have to figure out how to do the same steps in Python.
Since this is for learning purposes only, you need to open stdout_example.txt
file with Python and load the content of that file into a stdout
variable. (available for download at the top of this blog post)
Open SOAP XML Response File In Python
Define a stdout_file_path
variable to set the path to the stdout_example.txt
file. Make sure you set the correct path – this value could be different depending on your OS and depending on where you have downloaded the stdout_example.txt
file.
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
print(stdout)
Before you move forward, I’d recommend testing out the above code, check if you can actually print(stdout)
the content of stdout_example.txt
file and see the full SOAP response.
Extract XML Data Tag Value With Regex
Now that you have stdout
variable with multiple SOAP responses, you have to figure out how to achieve the first step you did above – you need to somehow put everything else aside and extract only the content of SOAP XML <data>...</data>
tags.
I’m sure you can come up with multiple creative ways to find text in Python, but most likely you want to have the simplest, most efficient way of extracting certain strings out of a large text file.
And when it comes to efficiency you have to choose to use regular expressions (regex). I’ve talked about regex before here and here but none of those cases were as complicated as this one.
import re
import typing
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
for data_tag in data_tags:
print(data_tag)
Since you’re looking to extract the content of all SOAP XML <data>...</data>
tags, you have to come up with a regular expression to select all of them.
Regular expression package in Python is accessible through import re
(line 1)
Then, instead of using other Python regex methods, you want to use re.findall to find all matches of a regex pattern in a string.
Now that you have a clear idea of why you should use re.findall, you also need to come up with a regex pattern to find the content of all SOAP XML <data>...</data>
tags.
Here I can’t really help you unless you spend some time understanding regex patterns yourself. Obviously, I’m giving you here an example of which pattern did I use:
regex_pattern = r'<data\b[^>]*>(.*?)</data>'
But to have a better understanding of regex patterns I’d recommend you to spend some time exploring situations described in the following regex posts I wrote some time ago – here and here. And also take a look at Python regex syntax here.
But just to give you a quick idea of what’s going on begin the above regex pattern here’s a screenshot from Python regex101 tool.
And the last bit that you need to know about is regex pattern matching with re.DOTALL
mode (line 12). The whole point of using it is that we have here a very long SOAP XML response and you want to look for <data>...</data>
tags through the whole response, not just one line.
re.DOTALL
mode means you’re going to assume .
(dot) is going to match not just a single line, but multiple lines of text including a new line. ( \n
)
And in the end, if you run the above code example, this is the output you should see:
<data>PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PENCLkI0Qi5BUFAuUkVRIHhtbG5zPSJ1cm46Q0JCNEJBUFBSRVE6eHNkOkNCLkI0Qi5BUFAuUkVRIiB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVRPC9UeXBlPjxDb250ZW50IElkPSJhNTNlOThlNC0wMTk3LTQ1MTMtYmU2ZC00OTgzNmU0MDZhYWEiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K1BFTkNMa0kwUWk1UVNVNUhMbEpGVVNCNGJXeHVjejBpZFhKdU9rTkNRalJDVUVsT1IxSkZVVHA0YzJRNlEwSXVRalJDTGxCSlRrY3VVa1ZSSWo0S0NUeFdZV3gxWlQ1UWFXNW5QQzlXWVd4MVpUNEtQQzlEUWk1Q05FSXVVRWxPUnk1U1JWRSs8L0NvbnRlbnQ+PFNpZ25hdHVyZXM+PFNpZ25hdHVyZSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFNpZ25lZEluZm8+PENhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxSZWZlcmVuY2UgVVJJPSIjYTUzZTk4ZTQtMDE5Ny00NTEzLWJlNmQtNDk4MzZlNDA2YWFhIj48RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8+PERpZ2VzdFZhbHVlPnNOaG94ZjZBRUxmQjJTczZHQ3lKUkl2SEZ4TnZheFhTSEtXSGp6ZFVrVE09PC9EaWdlc3RWYWx1ZT48L1JlZmVyZW5jZT48L1NpZ25lZEluZm8+PFNpZ25hdHVyZVZhbHVlPllUdWtFYUxxcllKQmRZZWVMdTVuNlJ1NktKdGJQb3dMVXI1MFNqZXV1SWcxN0VGWTFjcVpuUTQzSkhibEE3M3FTbFZ2OW11VjJnQ3gmIzEzOwo5Ulh4SEdSYnVFd1pVNGxXMDRzdUdvOFVMOUxrMm9nMXA1b3pKYVY1czZra1l4TldiQXhmUlVTZHpadXdHNE1OeDluM3NudzhKY2pjJiMxMzsKVVo2Q3Q3MzF4YzdQZ1A0TTBJUnkxZHd6MjNBeldqOXE3U1BPTzI3WHVOK2R1Snk5aVVxMlpDQ1FhR3ZBRGxoNkllYjd5amZJRkk3VSYjMTM7ClYzeHdHTXZIYm1GTVVJQ2taSUFZcUFBTVMyUmh1Wmt1WEVxcm9oRWZ3U1djOVp1RjBDR3dWbjFEaEV0Z3N1SmQzampPNXl5b2dnZismIzEzOwp3L2VKWnNDbmJBbUZ5VzQyd3VhdDY1VFYweVpDV0FQbkpRNjVSSWdBenlleXJwZ05yZmsrNlloUHJpcHpnMkJUaVE4WGxGQUQxQUovJiMxMzsKZDVuOVF3YUQyMmFsZ2pTOGJDMm11MWxSWndXM0l6MVJjMUZ0WjNQMGYrcmN6RmcxUVZ4NmJTOHNPUGdzWnhqWThOam9PRVJlWXRxLyYjMTM7Ck53eCs3ZVI2cE8zNnZxbmR6QnJpeGExdWxNRndHZEhwWHNUNVFhZGZFSGVhTmpKd3dxa3JGRDRvSkJuZGpnSHFGQnh3MzNVaUtzdWsmIzEzOwo2Tm9NUkh0dmcyN0N1UkJtVEdLUTNYZEc5dHpFSkZZUzJmdlJWWkhhczJUdy9WRUk3Tm5YOW4vVlF4eG9CMHdpbU9WTVNkbnVJOWx0JiMxMzsKeUxjRW1LQ2piU1M1VkRQSmp0RlpKSTIvZjdkTGNKdTEvMkZzdVE1d3RTdXN4TzRTaXdseWtUQ1pYdnBVeEJVS3l6b1lXZ0JIN2hBPTwvU2lnbmF0dXJlVmFsdWU+PEtleUluZm8+PFg1MDlEYXRhPjxYNTA5U3ViamVjdE5hbWU+Q049U3BlbGwsT1U9SVQsTz1TSUEgU3BlbGwsTD1SaWdhLFNUPUxhdHZpYSxDPUxWPC9YNTA5U3ViamVjdE5hbWU+PFg1MDlDZXJ0aWZpY2F0ZT5NSUlGV3pDQ0EwT2dBd0lCQWdJRVhyZDlVakFOQmdrcWhraUc5dzBCQVFzRkFEQmVNUXN3Q1FZRFZRUUdFd0pNVmpFUE1BMEdBMVVFJiMxMzsKQ0JNR1RHRjBkbWxoTVEwd0N3WURWUVFIRXdSU2FXZGhNUkl3RUFZRFZRUUtFd2xUU1VFZ1UzQmxiR3d4Q3pBSkJnTlZCQXNUQWtsVSYjMTM7Ck1RNHdEQVlEVlFRREV3VlRjR1ZzYkRBZUZ3MHlNVEV5TVRBd09UUTBOVFJhRncweU16RXhNekF3T1RRME5UUmFNRjR4Q3pBSkJnTlYmIzEzOwpCQVlUQWt4V01ROHdEUVlEVlFRSUV3Wk1ZWFIyYVdFeERUQUxCZ05WQkFjVEJGSnBaMkV4RWpBUUJnTlZCQW9UQ1ZOSlFTQlRjR1ZzJiMxMzsKYkRFTE1Ba0dBMVVFQ3hNQ1NWUXhEakFNQmdOVkJBTVRCVk53Wld4c01JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQyYjMTM7CkNnS0NBZ0VBakliN3JQektlQmtldXltVGN3Tys2WDlMd1o0ME1MNkxoUnJ0VzFoSlplVzA4SUtldldDVjZMVjZBMHJROXU3eUxOVmwmIzEzOwpNdGNtaTNIeE1jK2F6aTh4UC9aQmpENlhCSDVya1Y4OTI3YXlMRUp2R3MxL2VUbUlSZzBrQ2ttMDBBMU1selRzdEFoOWlhcnYxamNWJiMxMzsKWTdnb0ZMRURPOGFHYjczRU1MQVJxRzc1QUc1T09jS2wrZ2dTOGxDa2hzQlFjbHM4dndyc1VWRjhBM0VxOHVCYmZhcms2UDhGMGdXQyYjMTM7Cmk1aXZReEo3dVY3cGhlbXRPb1ZDOG84Z2kxSWhaYVZhejJkaWRXN2FTY2pKd0ZQRHhTcU5FOXlpbHFicGsrMmRBSmJ5ZUZucEdseXcmIzEzOwpZM1dyUnUya2NncStpRlczbCtrMlBDT21SNzF6OWlVdG9kbWoyOXpBZ1hHN2JkeUV1WG9ydGYrdm1HeGo1RjJhVFlxaHd2ckZPaG5wJiMxMzsKeGk5OVFISEE5R3AvRUVEU0g5V0R3ZmhCb05IRHcxQTAvbmUxK0F3ZisvSkRqN0hRaWVxSWFydVdqWHpIZjFmL1FlWlBlUEF1UWllMyYjMTM7CjZ6UE1NNjM0cnlqZkxOK0grVUtXV3RuRWJJOUlHREUzWERENzV6ZnAydXZSenN0ZE9JaStnUEJLaEUzV0lpRzJOS3JyUnBPZTlwL1QmIzEzOwpnRXBtMy9mT3VxZXNnWFArN2Z2aXNNTUh1bDQzcDltZ3Q2YVZWVUVYSjl0aFJDanJjOSsrUDRQRjRva3JyNEVseC9HL0paMlFaZE5aJiMxMzsKRDNvejlPUkJnZ0gyQUxwenNZVHphN24xSWhGckhtRmFkNklzb0t2RE9HOVdwNDdZSlo1OG81SitpZU1vaFhUY292Vnd3enZUeVc2eCYjMTM7CmVINkVJeU1DQXdFQUFhTWhNQjh3SFFZRFZSME9CQllFRkl3YXRyS21CeTZjTXorT2hxWjY5SFFZK2V0L01BMEdDU3FHU0liM0RRRUImIzEzOwpDd1VBQTRJQ0FRQUkrb0FNcEdCVDZnVUlsL01NS2R1Z3ZBbkJnVGVuL2xrakZyY0NEeVBRenJwNWtHYUtkU3pYYzdJdkpPRURac2p6JiMxMzsKZUV1N2lkSys0WWd5QTJ0VS9FT0lzdVVNTmQ4WkQvV1ExMGdyWG9yRWExWnFnUEhPd2dFcGJXcjNMbjJTaG9hdXF0Z2JOb0QyT2VFTyYjMTM7CnRnYWNYRkdDdUUwN2ZudXN6Q3JCMWVIQzJOb2F5Kzdudy95dzVKWmMrYjBKTnk4UGhqRTNHMlNvcG5SVUNNR1NhNEF0ckEwL0o4MTImIzEzOwo5Rmt1eHpyNVZrUUpXUFZnVnlEOVNaVGxDMGpjWkVxODdieUVWaDhxTDJ1ZlVObjk2ZmwyWDZnNzdCbkp5U3VaRk9LdHFhZWNrQ2xIJiMxMzsKVGpqSTcxbnRnMVEzdElic2VGazRxbHVtL1pkREhZTFBjOEUvRDcva01MUVNXSWlpTnBjY3lHWUJMN0U5MGdLWFkvK1Q4Mis4TGRMeCYjMTM7CmRpQnFpRDNQdjN6TDQ2ZnArZHhLRXIwWFRTYjJVZmRpRkRmVkNqejgrUzkxZi9EcnZ4ZExhbmpHbDZraG0zU0tFNUMvdjU2V2NmYm4mIzEzOwpOYnd4Tk9aSThHQXJ2RVFSUVcwbzNtSDhFNjczeC9PTWp5UWxMSjJBK1JUOTI3ejJuREJsdmh1a3VzOUNUTE56L3JtTnNmNVRvTUs2JiMxMzsKb1h4bnNGbVpkZGRhVm10N1pjZmNyb1FNc2srb2NQZzNPZURheTJUNkhKUFFxa3N3V2R1R3lwVE00Y0ZkUUJRZEEzZFZ1ZDhXRVVzVSYjMTM7CkJPZm1kNjVDbWpUbzliZnRHM2E3WVNGUkdFb0w3aXZmZDAvVEUrUitqOUpQQllBbmUwVnMzaEJwYVFnLzdMSW9MWjk1VmZsSnhYbHImIzEzOwo1d0dLblkzZXZBPT08L1g1MDlDZXJ0aWZpY2F0ZT48L1g1MDlEYXRhPjwvS2V5SW5mbz48L1NpZ25hdHVyZT48L1NpZ25hdHVyZXM+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSI3YTM2ZGZkNC0wMTBlLTRjNTQtOGQwOC1hMmU1OTk0NmEyMmMiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSIxOTBiOTYwNC1lODUyLTQ2ZTEtOWY3My1jZjA4OWNjMGMyYjQiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI0OTgzYTE0MS1mN2JlLTQzN2QtOGYwMS03NjE1M2RiMTYxMzYiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU56VTVOamc4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ERXRNalJVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStSMDh6TUZCVFRFYzROa280Vms1R05Ud3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5EVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpGbE56STJZamcyTWpOak1qUTBOVFJpWVRjMVl6QTNOelprTXpZNVkyWmlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrZFRNVGhPT0U0MVZFSlNNMDh3UEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhaVGN5Tm1JNE5qSXpZekkwTkRVMFltRTNOV013TnpjMlpETTJPV05tWWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTBOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9FWEVDPC9UeXBlPjxDb250ZW50IElkPSI3NmZjMWYzYS1kMWE0LTQ5MDItOTY3Ny02ZmRjYWQ1Nzg3NzkiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU56VTVOekU4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ERXRNalJVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStSMDh6TUZCVFRFYzROa280Vms1R05Ud3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5UVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpGbE56STJZamcyTWpOak1qUTBOVFJpWVRjMVl6QTNOelprTXpZNVkyWmlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrZFRNVGhPT0U0MVZFSlNNMDh3UEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhaVGN5Tm1JNE5qSXpZekkwTkRVMFltRTNOV013TnpjMlpETTJPV05tWWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTFOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI0MDNlMmQzNC1kNzcxLTQ5YmQtOTgxZi0xYTJlZTIzYzlmN2QiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOVFk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStTVVZDVGxKSE5WVTFWazlJU0ZWSU5Ed3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpnMFptVXhNbU01TURJeU56UTJZVEZoTW1JMk4yVXdPVFUwWldNMU5EQXdQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrRkNTREk0T1ZKVlUxRldUVUpFUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENDROR1psTVRKak9UQXlNamMwTm1FeFlUSmlOamRsTURrMU5HVmpOVFF3TUR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI2M2ZhODY5Ny03NGI4LTQyZjEtOGJiZC0zNDcxMmNjNWFlYmUiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOamc4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStNa1JSU0ZaR01FUkVRalJKT0RaSFRUd3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpCak1qWTRObVJrTW1Jd1pqUXlNbVk1T0RZeE16UmxabVl3WTJFNU9UbGlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BqRk1Wa1pMUXpBM01GVk9NVGRCUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHdZekkyT0Raa1pESmlNR1kwTWpKbU9UZzJNVE0wWldabU1HTmhPVGs1WWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSIxZTZlNmYxMS03YTYyLTRhN2ItYjRlNC1kNThkNmJhYjEwNWEiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOekk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStVRkZLUmtwRFJVUTVRazR6U0RCUE1Ed3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUG1NMU9HRmlPRFJoWXpZM016UTVaakpoTlRkak9UWmlOalkzWmpJNU9UazBQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BqTlVWVUZXVDBSRVFqQk9WREZLUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENWpOVGhoWWpnMFlXTTJOek0wT1dZeVlUVTNZemsyWWpZMk4yWXlPVGs1TkR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSJjYTg4N2NjMC1kYTJjLTRiZjctODU0Ny01NDRlOTkxYzgwNjIiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOelk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStPVWMxVGxOUVUxRklVVGhJUjBGU1V6d3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5EVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpFM1pESTNNek16TVRRM09EUXhObVE1Wm1KbFl6STBOemRtTlRWaU1EQmxQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BsSlBUVU5OUjBOTlZqVkhVMEZXUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhOMlF5TnpNek16RTBOemcwTVRaa09XWmlaV015TkRjM1pqVTFZakF3WlR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTBOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9FWEVDPC9UeXBlPjxDb250ZW50IElkPSJhYmVkODRjZC0xYTM0LTQxMmEtODUyMi0yNjhkYTNhOWIxNGUiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOems4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStPVWMxVGxOUVUxRklVVGhJUjBGU1V6d3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5UVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpFM1pESTNNek16TVRRM09EUXhObVE1Wm1KbFl6STBOemRtTlRWaU1EQmxQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BsSlBUVU5OUjBOTlZqVkhVMEZXUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhOMlF5TnpNek16RTBOemcwTVRaa09XWmlaV015TkRjM1pqVTFZakF3WlR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTFOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSJhYjk3Njk1Yi05YmRkLTQ0NzYtYTJjOS02OTQ1YzEyOTcxNTkiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iMjUyYWYyYzgtZDlmOC00ZTA4LTlmNTEtYmNmMjNkN2RhNTVhIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iOTIzYjk1YjctZDgwZi00YTcwLWExNjItOGY2Zjg2NjE3N2E0Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iOWM4MGZkMWEtYWEyYS00Zjc1LThlYmEtZDgxMzM5MDFkZjYxIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iY2E5N2VkNjAtMTRjMi00ZjhlLTg2ZjctZmIyMmJjZjEyYjE0Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iZTA0NzQyZDgtZmRkNy00ZjE4LTgxZjItMjQ4N2Y5MjhhZmRmIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iMDY2YTVlZWQtMTJiMi00ZTM4LTg1Y2EtYjRiMjQxYWY2ZGE3Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
Remove Data Tag To Have Pure Base64 Value
The next step is pretty clear, if you take another glance at the output above, you’ll notice a <data>
tag laying round. This is a result of an imperfect regex pattern. Yeah, you could make your regex patterns perfect and perfectly extract only the text you’re looking for…
BUT, when it comes to building a product it’s more about results and SPEED.
I prefer using a simple solution here, instead of tweaking a regex pattern that already does 99% of the work, I’d apply .replace('<data>', '')
to replace the opening data tag with an empty string .replace('</data>', '')
to replace a closing data tag with an empty string.
import re
import typing
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
responses = []
for data_tag in data_tags:
res_base64: str = (
data_tag
.replace('<data>', '')
.replace('</data>', '')
)
print(res_base64)
And output after executing the code example above should be a list of very clear base64 strings – ready to be decoded.
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PENCLkI0Qi5BUFAuUkVRIHhtbG5zPSJ1cm46Q0JCNEJBUFBSRVE6eHNkOkNCLkI0Qi5BUFAuUkVRIiB4bWxuczpkcz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVRPC9UeXBlPjxDb250ZW50IElkPSJhNTNlOThlNC0wMTk3LTQ1MTMtYmU2ZC00OTgzNmU0MDZhYWEiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbTV2SWo4K1BFTkNMa0kwUWk1UVNVNUhMbEpGVVNCNGJXeHVjejBpZFhKdU9rTkNRalJDVUVsT1IxSkZVVHA0YzJRNlEwSXVRalJDTGxCSlRrY3VVa1ZSSWo0S0NUeFdZV3gxWlQ1UWFXNW5QQzlXWVd4MVpUNEtQQzlEUWk1Q05FSXVVRWxPUnk1U1JWRSs8L0NvbnRlbnQ+PFNpZ25hdHVyZXM+PFNpZ25hdHVyZSB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC8wOS94bWxkc2lnIyI+PFNpZ25lZEluZm8+PENhbm9uaWNhbGl6YXRpb25NZXRob2QgQWxnb3JpdGhtPSJodHRwOi8vd3d3LnczLm9yZy8yMDAxLzEwL3htbC1leGMtYzE0biMiLz48U2lnbmF0dXJlTWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxkc2lnLW1vcmUjcnNhLXNoYTI1NiIvPjxSZWZlcmVuY2UgVVJJPSIjYTUzZTk4ZTQtMDE5Ny00NTEzLWJlNmQtNDk4MzZlNDA2YWFhIj48RGlnZXN0TWV0aG9kIEFsZ29yaXRobT0iaHR0cDovL3d3dy53My5vcmcvMjAwMS8wNC94bWxlbmMjc2hhMjU2Ii8+PERpZ2VzdFZhbHVlPnNOaG94ZjZBRUxmQjJTczZHQ3lKUkl2SEZ4TnZheFhTSEtXSGp6ZFVrVE09PC9EaWdlc3RWYWx1ZT48L1JlZmVyZW5jZT48L1NpZ25lZEluZm8+PFNpZ25hdHVyZVZhbHVlPllUdWtFYUxxcllKQmRZZWVMdTVuNlJ1NktKdGJQb3dMVXI1MFNqZXV1SWcxN0VGWTFjcVpuUTQzSkhibEE3M3FTbFZ2OW11VjJnQ3gmIzEzOwo5Ulh4SEdSYnVFd1pVNGxXMDRzdUdvOFVMOUxrMm9nMXA1b3pKYVY1czZra1l4TldiQXhmUlVTZHpadXdHNE1OeDluM3NudzhKY2pjJiMxMzsKVVo2Q3Q3MzF4YzdQZ1A0TTBJUnkxZHd6MjNBeldqOXE3U1BPTzI3WHVOK2R1Snk5aVVxMlpDQ1FhR3ZBRGxoNkllYjd5amZJRkk3VSYjMTM7ClYzeHdHTXZIYm1GTVVJQ2taSUFZcUFBTVMyUmh1Wmt1WEVxcm9oRWZ3U1djOVp1RjBDR3dWbjFEaEV0Z3N1SmQzampPNXl5b2dnZismIzEzOwp3L2VKWnNDbmJBbUZ5VzQyd3VhdDY1VFYweVpDV0FQbkpRNjVSSWdBenlleXJwZ05yZmsrNlloUHJpcHpnMkJUaVE4WGxGQUQxQUovJiMxMzsKZDVuOVF3YUQyMmFsZ2pTOGJDMm11MWxSWndXM0l6MVJjMUZ0WjNQMGYrcmN6RmcxUVZ4NmJTOHNPUGdzWnhqWThOam9PRVJlWXRxLyYjMTM7Ck53eCs3ZVI2cE8zNnZxbmR6QnJpeGExdWxNRndHZEhwWHNUNVFhZGZFSGVhTmpKd3dxa3JGRDRvSkJuZGpnSHFGQnh3MzNVaUtzdWsmIzEzOwo2Tm9NUkh0dmcyN0N1UkJtVEdLUTNYZEc5dHpFSkZZUzJmdlJWWkhhczJUdy9WRUk3Tm5YOW4vVlF4eG9CMHdpbU9WTVNkbnVJOWx0JiMxMzsKeUxjRW1LQ2piU1M1VkRQSmp0RlpKSTIvZjdkTGNKdTEvMkZzdVE1d3RTdXN4TzRTaXdseWtUQ1pYdnBVeEJVS3l6b1lXZ0JIN2hBPTwvU2lnbmF0dXJlVmFsdWU+PEtleUluZm8+PFg1MDlEYXRhPjxYNTA5U3ViamVjdE5hbWU+Q049U3BlbGwsT1U9SVQsTz1TSUEgU3BlbGwsTD1SaWdhLFNUPUxhdHZpYSxDPUxWPC9YNTA5U3ViamVjdE5hbWU+PFg1MDlDZXJ0aWZpY2F0ZT5NSUlGV3pDQ0EwT2dBd0lCQWdJRVhyZDlVakFOQmdrcWhraUc5dzBCQVFzRkFEQmVNUXN3Q1FZRFZRUUdFd0pNVmpFUE1BMEdBMVVFJiMxMzsKQ0JNR1RHRjBkbWxoTVEwd0N3WURWUVFIRXdSU2FXZGhNUkl3RUFZRFZRUUtFd2xUU1VFZ1UzQmxiR3d4Q3pBSkJnTlZCQXNUQWtsVSYjMTM7Ck1RNHdEQVlEVlFRREV3VlRjR1ZzYkRBZUZ3MHlNVEV5TVRBd09UUTBOVFJhRncweU16RXhNekF3T1RRME5UUmFNRjR4Q3pBSkJnTlYmIzEzOwpCQVlUQWt4V01ROHdEUVlEVlFRSUV3Wk1ZWFIyYVdFeERUQUxCZ05WQkFjVEJGSnBaMkV4RWpBUUJnTlZCQW9UQ1ZOSlFTQlRjR1ZzJiMxMzsKYkRFTE1Ba0dBMVVFQ3hNQ1NWUXhEakFNQmdOVkJBTVRCVk53Wld4c01JSUNJakFOQmdrcWhraUc5dzBCQVFFRkFBT0NBZzhBTUlJQyYjMTM7CkNnS0NBZ0VBakliN3JQektlQmtldXltVGN3Tys2WDlMd1o0ME1MNkxoUnJ0VzFoSlplVzA4SUtldldDVjZMVjZBMHJROXU3eUxOVmwmIzEzOwpNdGNtaTNIeE1jK2F6aTh4UC9aQmpENlhCSDVya1Y4OTI3YXlMRUp2R3MxL2VUbUlSZzBrQ2ttMDBBMU1selRzdEFoOWlhcnYxamNWJiMxMzsKWTdnb0ZMRURPOGFHYjczRU1MQVJxRzc1QUc1T09jS2wrZ2dTOGxDa2hzQlFjbHM4dndyc1VWRjhBM0VxOHVCYmZhcms2UDhGMGdXQyYjMTM7Cmk1aXZReEo3dVY3cGhlbXRPb1ZDOG84Z2kxSWhaYVZhejJkaWRXN2FTY2pKd0ZQRHhTcU5FOXlpbHFicGsrMmRBSmJ5ZUZucEdseXcmIzEzOwpZM1dyUnUya2NncStpRlczbCtrMlBDT21SNzF6OWlVdG9kbWoyOXpBZ1hHN2JkeUV1WG9ydGYrdm1HeGo1RjJhVFlxaHd2ckZPaG5wJiMxMzsKeGk5OVFISEE5R3AvRUVEU0g5V0R3ZmhCb05IRHcxQTAvbmUxK0F3ZisvSkRqN0hRaWVxSWFydVdqWHpIZjFmL1FlWlBlUEF1UWllMyYjMTM7CjZ6UE1NNjM0cnlqZkxOK0grVUtXV3RuRWJJOUlHREUzWERENzV6ZnAydXZSenN0ZE9JaStnUEJLaEUzV0lpRzJOS3JyUnBPZTlwL1QmIzEzOwpnRXBtMy9mT3VxZXNnWFArN2Z2aXNNTUh1bDQzcDltZ3Q2YVZWVUVYSjl0aFJDanJjOSsrUDRQRjRva3JyNEVseC9HL0paMlFaZE5aJiMxMzsKRDNvejlPUkJnZ0gyQUxwenNZVHphN24xSWhGckhtRmFkNklzb0t2RE9HOVdwNDdZSlo1OG81SitpZU1vaFhUY292Vnd3enZUeVc2eCYjMTM7CmVINkVJeU1DQXdFQUFhTWhNQjh3SFFZRFZSME9CQllFRkl3YXRyS21CeTZjTXorT2hxWjY5SFFZK2V0L01BMEdDU3FHU0liM0RRRUImIzEzOwpDd1VBQTRJQ0FRQUkrb0FNcEdCVDZnVUlsL01NS2R1Z3ZBbkJnVGVuL2xrakZyY0NEeVBRenJwNWtHYUtkU3pYYzdJdkpPRURac2p6JiMxMzsKZUV1N2lkSys0WWd5QTJ0VS9FT0lzdVVNTmQ4WkQvV1ExMGdyWG9yRWExWnFnUEhPd2dFcGJXcjNMbjJTaG9hdXF0Z2JOb0QyT2VFTyYjMTM7CnRnYWNYRkdDdUUwN2ZudXN6Q3JCMWVIQzJOb2F5Kzdudy95dzVKWmMrYjBKTnk4UGhqRTNHMlNvcG5SVUNNR1NhNEF0ckEwL0o4MTImIzEzOwo5Rmt1eHpyNVZrUUpXUFZnVnlEOVNaVGxDMGpjWkVxODdieUVWaDhxTDJ1ZlVObjk2ZmwyWDZnNzdCbkp5U3VaRk9LdHFhZWNrQ2xIJiMxMzsKVGpqSTcxbnRnMVEzdElic2VGazRxbHVtL1pkREhZTFBjOEUvRDcva01MUVNXSWlpTnBjY3lHWUJMN0U5MGdLWFkvK1Q4Mis4TGRMeCYjMTM7CmRpQnFpRDNQdjN6TDQ2ZnArZHhLRXIwWFRTYjJVZmRpRkRmVkNqejgrUzkxZi9EcnZ4ZExhbmpHbDZraG0zU0tFNUMvdjU2V2NmYm4mIzEzOwpOYnd4Tk9aSThHQXJ2RVFSUVcwbzNtSDhFNjczeC9PTWp5UWxMSjJBK1JUOTI3ejJuREJsdmh1a3VzOUNUTE56L3JtTnNmNVRvTUs2JiMxMzsKb1h4bnNGbVpkZGRhVm10N1pjZmNyb1FNc2srb2NQZzNPZURheTJUNkhKUFFxa3N3V2R1R3lwVE00Y0ZkUUJRZEEzZFZ1ZDhXRVVzVSYjMTM7CkJPZm1kNjVDbWpUbzliZnRHM2E3WVNGUkdFb0w3aXZmZDAvVEUrUitqOUpQQllBbmUwVnMzaEJwYVFnLzdMSW9MWjk1VmZsSnhYbHImIzEzOwo1d0dLblkzZXZBPT08L1g1MDlDZXJ0aWZpY2F0ZT48L1g1MDlEYXRhPjwvS2V5SW5mbz48L1NpZ25hdHVyZT48L1NpZ25hdHVyZXM+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSI3YTM2ZGZkNC0wMTBlLTRjNTQtOGQwOC1hMmU1OTk0NmEyMmMiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSIxOTBiOTYwNC1lODUyLTQ2ZTEtOWY3My1jZjA4OWNjMGMyYjQiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI0OTgzYTE0MS1mN2JlLTQzN2QtOGYwMS03NjE1M2RiMTYxMzYiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU56VTVOamc4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ERXRNalJVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStSMDh6TUZCVFRFYzROa280Vms1R05Ud3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5EVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpGbE56STJZamcyTWpOak1qUTBOVFJpWVRjMVl6QTNOelprTXpZNVkyWmlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrZFRNVGhPT0U0MVZFSlNNMDh3UEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhaVGN5Tm1JNE5qSXpZekkwTkRVMFltRTNOV013TnpjMlpETTJPV05tWWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTBOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9FWEVDPC9UeXBlPjxDb250ZW50IElkPSI3NmZjMWYzYS1kMWE0LTQ5MDItOTY3Ny02ZmRjYWQ1Nzg3NzkiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU56VTVOekU4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ERXRNalJVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStSMDh6TUZCVFRFYzROa280Vms1R05Ud3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5UVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpGbE56STJZamcyTWpOak1qUTBOVFJpWVRjMVl6QTNOelprTXpZNVkyWmlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrZFRNVGhPT0U0MVZFSlNNMDh3UEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhaVGN5Tm1JNE5qSXpZekkwTkRVMFltRTNOV013TnpjMlpETTJPV05tWWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTFOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI0MDNlMmQzNC1kNzcxLTQ5YmQtOTgxZi0xYTJlZTIzYzlmN2QiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOVFk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStTVVZDVGxKSE5WVTFWazlJU0ZWSU5Ed3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpnMFptVXhNbU01TURJeU56UTJZVEZoTW1JMk4yVXdPVFUwWldNMU5EQXdQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BrRkNTREk0T1ZKVlUxRldUVUpFUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENDROR1psTVRKak9UQXlNamMwTm1FeFlUSmlOamRsTURrMU5HVmpOVFF3TUR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSI2M2ZhODY5Ny03NGI4LTQyZjEtOGJiZC0zNDcxMmNjNWFlYmUiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOamc4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStNa1JSU0ZaR01FUkVRalJKT0RaSFRUd3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpCak1qWTRObVJrTW1Jd1pqUXlNbVk1T0RZeE16UmxabVl3WTJFNU9UbGlQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BqRk1Wa1pMUXpBM01GVk9NVGRCUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHdZekkyT0Raa1pESmlNR1kwTWpKbU9UZzJNVE0wWldabU1HTmhPVGs1WWp3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSIxZTZlNmYxMS03YTYyLTRhN2ItYjRlNC1kNThkNmJhYjEwNWEiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOekk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStVRkZLUmtwRFJVUTVRazR6U0RCUE1Ed3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStVa3BEVkR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUG1NMU9HRmlPRFJoWXpZM016UTVaakpoTlRkak9UWmlOalkzWmpJNU9UazBQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BqTlVWVUZXVDBSRVFqQk9WREZLUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENWpOVGhoWWpnMFlXTTJOek0wT1dZeVlUVTNZemsyWWpZMk4yWXlPVGs1TkR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVTU2tOVVBDOVVlRk4wY3o0OFUzUnpVbk51U1c1bVBqeFNjMjQrUEVOa1BrNUJVbEk4TDBOa1Bqd3ZVbk51UGp4QlpHUjBiRWx1Wmo1TllXdHp4SUYweElGcVlTQnJiMjUwWVNCSlFrRk9PaUJKZW5iRWsyeHBaWFJwWlhNZ2EyOXVkR0VnYm5WdGRYSjFMand2UVdSa2RHeEpibVkrUEM5VGRITlNjMjVKYm1ZK1BDOVVlRWx1WmtGdVpGTjBjejQ4TDA5eVoyNXNVRzEwU1c1bVFXNWtVM1J6UGp3dlEzTjBiWEpRYlhSVGRITlNjSFErUEM5RWIyTjFiV1Z1ZEQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9SRVNQPC9UeXBlPjxDb250ZW50IElkPSJjYTg4N2NjMC1kYTJjLTRiZjctODU0Ny01NDRlOTkxYzgwNjIiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOelk4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStPVWMxVGxOUVUxRklVVGhJUjBGU1V6d3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5EVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpFM1pESTNNek16TVRRM09EUXhObVE1Wm1KbFl6STBOemRtTlRWaU1EQmxQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BsSlBUVU5OUjBOTlZqVkhVMEZXUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhOMlF5TnpNek16RTBOemcwTVRaa09XWmlaV015TkRjM1pqVTFZakF3WlR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTBOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BNVF9FWEVDPC9UeXBlPjxDb250ZW50IElkPSJhYmVkODRjZC0xYTM0LTQxMmEtODUyMi0yNjhkYTNhOWIxNGUiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeEViMk4xYldWdWRDQjRiV3h1Y3owaWRYSnVPbWx6YnpwemRHUTZhWE52T2pJd01ESXlPblJsWTJnNmVITmtPbkJoYVc0dU1EQXlMakF3TVM0d015SStQRU56ZEcxeVVHMTBVM1J6VW5CMFBqeEhjbkJJWkhJK1BFMXpaMGxrUGtkWE1EQXdNREF3TXpJNU9EQTJOems4TDAxelowbGtQanhEY21WRWRGUnRQakl3TWpJdE1ESXRNVEZVTURBNk1EQTZNREE4TDBOeVpVUjBWRzArUEVsdWFYUm5VSFI1UGp4SlpENDhUM0puU1dRK1BFSkpRMDl5UWtWSlBsQkJVbGhNVmpJeVBDOUNTVU5QY2tKRlNUNDhMMDl5WjBsa1Bqd3ZTV1ErUEM5SmJtbDBaMUIwZVQ0OEwwZHljRWhrY2o0OFQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVFhOblNXUStPVWMxVGxOUVUxRklVVGhJUjBGU1V6d3ZUM0puYm14TmMyZEpaRDQ4VDNKbmJteE5jMmRPYlVsa1BuQmhhVzR1TURBeExqQXdNUzR3TXp3dlQzSm5ibXhOYzJkT2JVbGtQanhIY25CVGRITStRVU5UVUR3dlIzSndVM1J6UGp3dlQzSm5ibXhIY25CSmJtWkJibVJUZEhNK1BFOXlaMjVzVUcxMFNXNW1RVzVrVTNSelBqeFBjbWR1YkZCdGRFbHVaa2xrUGpFM1pESTNNek16TVRRM09EUXhObVE1Wm1KbFl6STBOemRtTlRWaU1EQmxQQzlQY21kdWJGQnRkRWx1Wmtsa1BqeFVlRWx1WmtGdVpGTjBjejQ4VDNKbmJteEpibk4wY2tsa1BsSlBUVU5OUjBOTlZqVkhVMEZXUEM5UGNtZHViRWx1YzNSeVNXUStQRTl5WjI1c1JXNWtWRzlGYm1SSlpENHhOMlF5TnpNek16RTBOemcwTVRaa09XWmlaV015TkRjM1pqVTFZakF3WlR3dlQzSm5ibXhGYm1SVWIwVnVaRWxrUGp4VWVGTjBjejVCUTFOUVBDOVVlRk4wY3o0OEwxUjRTVzVtUVc1a1UzUnpQand2VDNKbmJteFFiWFJKYm1aQmJtUlRkSE0rUEM5RGMzUnRjbEJ0ZEZOMGMxSndkRDQ4TDBSdlkzVnRaVzUwUGc9PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX0VSUk9SPC9UeXBlPjxDb250ZW50IElkPSJhYjk3Njk1Yi05YmRkLTQ0NzYtYTJjOS02OTQ1YzEyOTcxNTkiPlBEOTRiV3dnZG1WeWMybHZiajBpTVM0d0lpQmxibU52WkdsdVp6MGlWVlJHTFRnaUlITjBZVzVrWVd4dmJtVTlJbmxsY3lJL1BqeERRaTVDTkVJdVJWSlNUMUlnZUcxc2JuTTlJblZ5YmpwRFFrSTBRa1ZTVWs5U09uaHpaRHBEUWk1Q05FSXVSVkpTVDFJaVBqeERiMlJsUGtWWVExOUhRVlJGVjBGWlgwSTBRbDlUUTBoRlRVRmZWa0ZNU1VSQlZFbFBUbDlGVWxKUFVqd3ZRMjlrWlQ0OFRXVnpjMkZuWlQ1RmNuSnZjaUJ6WTJobGJXRWdkbUZzYVdSaGRHbHZiand2VFdWemMyRm5aVDQ4TDBOQ0xrSTBRaTVGVWxKUFVqND08L0NvbnRlbnQ+PC9DQi5CNEIuQVBQLlJFUT4=
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iMjUyYWYyYzgtZDlmOC00ZTA4LTlmNTEtYmNmMjNkN2RhNTVhIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iOTIzYjk1YjctZDgwZi00YTcwLWExNjItOGY2Zjg2NjE3N2E0Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iOWM4MGZkMWEtYWEyYS00Zjc1LThlYmEtZDgxMzM5MDFkZjYxIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iY2E5N2VkNjAtMTRjMi00ZjhlLTg2ZjctZmIyMmJjZjEyYjE0Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iZTA0NzQyZDgtZmRkNy00ZjE4LTgxZjItMjQ4N2Y5MjhhZmRmIj5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuQVBQLlJFUSB4bWxucz0idXJuOkNCQjRCQVBQUkVROnhzZDpDQi5CNEIuQVBQLlJFUSI+PFR5cGU+Q0JfQjRCX1BJTkdfUkVTUDwvVHlwZT48Q29udGVudCBJZD0iMDY2YTVlZWQtMTJiMi00ZTM4LTg1Y2EtYjRiMjQxYWY2ZGE3Ij5QRDk0Yld3Z2RtVnljMmx2YmowaU1TNHdJaUJsYm1OdlpHbHVaejBpVlZSR0xUZ2lJSE4wWVc1a1lXeHZibVU5SW5sbGN5SS9QanhEUWk1Q05FSXVVRWxPUnk1U1JWTlFJSGh0Ykc1elBTSjFjbTQ2UTBKQ05FSlFTVTVIVWtWVFVEcDRjMlE2UTBJdVFqUkNMbEJKVGtjdVVrVlRVQ0krUEZaaGJIVmxQbEJwYm1jOEwxWmhiSFZsUGp3dlEwSXVRalJDTGxCSlRrY3VVa1ZUVUQ0PTwvQ29udGVudD48L0NCLkI0Qi5BUFAuUkVRPg==
So, that’s the next step, let’s base64 decode each string with Python.
Decode Base64 Response With Python
When it comes to decoding and working with unknown input values you automatically have to assume the whole script is going end to end up in an exception at some point.
You can’t guarantee SOAP response won’t consist of some kind of garbage, so it’s better to assume the worse.
What do I mean by that? See the screenshot below:
With base64.b64decode(res_base64).decode('utf-8')
you’re expecting to have base64 string inside a res_base64
variable and decode it.
The key thing here is to use try/except block.
You can’t be 100% sure res_base64
variable will always be a pure base64 string easily decodable.
Especially, when you work with external API, you can never be sure what’s going to come back from there.
So, if base64.b64decode(res_base64).decode('utf-8')
the line would fail with a decoding exception, which would raise an binascii.Error
exception.
import re
import typing
import base64
import binascii
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
responses = []
for data_tag in data_tags:
res_base64: str = (
data_tag
.replace('<data>', '')
.replace('</data>', '')
)
try:
response: str = (
base64
.b64decode(res_base64)
.decode('utf-8')
)
except binascii.Error:
continue
print(response)
And the result, if you execute the above code example is the output below. You can already see we’re getting better results, more human-readable responses.
<?xml version="1.0" encoding="UTF-8" standalone="no"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><Type>CB_B4B_PING_REQ</Type><Content Id="a53e98e4-0197-4513-be6d-49836e406aaa">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9Im5vIj8+PENCLkI0Qi5QSU5HLlJFUSB4bWxucz0idXJuOkNCQjRCUElOR1JFUTp4c2Q6Q0IuQjRCLlBJTkcuUkVRIj4KCTxWYWx1ZT5QaW5nPC9WYWx1ZT4KPC9DQi5CNEIuUElORy5SRVE+</Content><Signatures><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI="#a53e98e4-0197-4513-be6d-49836e406aaa"><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>sNhoxf6AELfB2Ss6GCyJRIvHFxNvaxXSHKWHjzdUkTM=</DigestValue></Reference></SignedInfo><SignatureValue>YTukEaLqrYJBdYeeLu5n6Ru6KJtbPowLUr50SjeuuIg17EFY1cqZnQ43JHblA73qSlVv9muV2gCx
9RXxHGRbuEwZU4lW04suGo8UL9Lk2og1p5ozJaV5s6kkYxNWbAxfRUSdzZuwG4MNx9n3snw8Jcjc
UZ6Ct731xc7PgP4M0IRy1dwz23AzWj9q7SPOO27XuN+duJy9iUq2ZCCQaGvADlh6Ieb7yjfIFI7U
V3xwGMvHbmFMUICkZIAYqAAMS2RhuZkuXEqrohEfwSWc9ZuF0CGwVn1DhEtgsuJd3jjO5yyoggf+
w/eJZsCnbAmFyW42wuat65TV0yZCWAPnJQ65RIgAzyeyrpgNrfk+6YhPripzg2BTiQ8XlFAD1AJ/
d5n9QwaD22algjS8bC2mu1lRZwW3Iz1Rc1FtZ3P0f+rczFg1QVx6bS8sOPgsZxjY8NjoOEReYtq/
Nwx+7eR6pO36vqndzBrixa1ulMFwGdHpXsT5QadfEHeaNjJwwqkrFD4oJBndjgHqFBxw33UiKsuk
6NoMRHtvg27CuRBmTGKQ3XdG9tzEJFYS2fvRVZHas2Tw/VEI7NnX9n/VQxxoB0wimOVMSdnuI9lt
yLcEmKCjbSS5VDPJjtFZJI2/f7dLcJu1/2FsuQ5wtSusxO4SiwlykTCZXvpUxBUKyzoYWgBH7hA=</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=Spell,OU=IT,O=SIA Spell,L=Riga,ST=Latvia,C=LV</X509SubjectName><X509Certificate>MIIFWzCCA0OgAwIBAgIEXrd9UjANBgkqhkiG9w0BAQsFADBeMQswCQYDVQQGEwJMVjEPMA0GA1UE
CBMGTGF0dmlhMQ0wCwYDVQQHEwRSaWdhMRIwEAYDVQQKEwlTSUEgU3BlbGwxCzAJBgNVBAsTAklU
MQ4wDAYDVQQDEwVTcGVsbDAeFw0yMTEyMTAwOTQ0NTRaFw0yMzExMzAwOTQ0NTRaMF4xCzAJBgNV
BAYTAkxWMQ8wDQYDVQQIEwZMYXR2aWExDTALBgNVBAcTBFJpZ2ExEjAQBgNVBAoTCVNJQSBTcGVs
bDELMAkGA1UECxMCSVQxDjAMBgNVBAMTBVNwZWxsMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
CgKCAgEAjIb7rPzKeBkeuymTcwO+6X9LwZ40ML6LhRrtW1hJZeW08IKevWCV6LV6A0rQ9u7yLNVl
Mtcmi3HxMc+azi8xP/ZBjD6XBH5rkV8927ayLEJvGs1/eTmIRg0kCkm00A1MlzTstAh9iarv1jcV
Y7goFLEDO8aGb73EMLARqG75AG5OOcKl+ggS8lCkhsBQcls8vwrsUVF8A3Eq8uBbfark6P8F0gWC
i5ivQxJ7uV7phemtOoVC8o8gi1IhZaVaz2didW7aScjJwFPDxSqNE9yilqbpk+2dAJbyeFnpGlyw
Y3WrRu2kcgq+iFW3l+k2PCOmR71z9iUtodmj29zAgXG7bdyEuXortf+vmGxj5F2aTYqhwvrFOhnp
xi99QHHA9Gp/EEDSH9WDwfhBoNHDw1A0/ne1+Awf+/JDj7HQieqIaruWjXzHf1f/QeZPePAuQie3
6zPMM634ryjfLN+H+UKWWtnEbI9IGDE3XDD75zfp2uvRzstdOIi+gPBKhE3WIiG2NKrrRpOe9p/T
gEpm3/fOuqesgXP+7fvisMMHul43p9mgt6aVVUEXJ9thRCjrc9++P4PF4okrr4Elx/G/JZ2QZdNZ
D3oz9ORBggH2ALpzsYTza7n1IhFrHmFad6IsoKvDOG9Wp47YJZ58o5J+ieMohXTcovVwwzvTyW6x
eH6EIyMCAwEAAaMhMB8wHQYDVR0OBBYEFIwatrKmBy6cMz+OhqZ69HQY+et/MA0GCSqGSIb3DQEB
CwUAA4ICAQAI+oAMpGBT6gUIl/MMKdugvAnBgTen/lkjFrcCDyPQzrp5kGaKdSzXc7IvJOEDZsjz
eEu7idK+4YgyA2tU/EOIsuUMNd8ZD/WQ10grXorEa1ZqgPHOwgEpbWr3Ln2ShoauqtgbNoD2OeEO
tgacXFGCuE07fnuszCrB1eHC2Noay+7nw/yw5JZc+b0JNy8PhjE3G2SopnRUCMGSa4AtrA0/J812
9Fkuxzr5VkQJWPVgVyD9SZTlC0jcZEq87byEVh8qL2ufUNn96fl2X6g77BnJySuZFOKtqaeckClH
TjjI71ntg1Q3tIbseFk4qlum/ZdDHYLPc8E/D7/kMLQSWIiiNpccyGYBL7E90gKXY/+T82+8LdLx
diBqiD3Pv3zL46fp+dxKEr0XTSb2UfdiFDfVCjz8+S91f/DrvxdLanjGl6khm3SKE5C/v56Wcfbn
NbwxNOZI8GArvEQRQW0o3mH8E673x/OMjyQlLJ2A+RT927z2nDBlvhukus9CTLNz/rmNsf5ToMK6
oXxnsFmZdddaVmt7ZcfcroQMsk+ocPg3OeDay2T6HJPQqkswWduGypTM4cFdQBQdA3dVud8WEUsU
BOfmd65CmjTo9bftG3a7YSFRGEoL7ivfd0/TE+R+j9JPBYAne0Vs3hBpaQg/7LIoLZ95VflJxXlr
5wGKnY3evA==</X509Certificate></X509Data></KeyInfo></Signature></Signatures></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_ERROR</Type><Content Id="7a36dfd4-010e-4c54-8d08-a2e59946a22c">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuRVJST1IgeG1sbnM9InVybjpDQkI0QkVSUk9SOnhzZDpDQi5CNEIuRVJST1IiPjxDb2RlPkVYQ19HQVRFV0FZX0I0Ql9TQ0hFTUFfVkFMSURBVElPTl9FUlJPUjwvQ29kZT48TWVzc2FnZT5FcnJvciBzY2hlbWEgdmFsaWRhdGlvbjwvTWVzc2FnZT48L0NCLkI0Qi5FUlJPUj4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_ERROR</Type><Content Id="190b9604-e852-46e1-9f73-cf089cc0c2b4">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuRVJST1IgeG1sbnM9InVybjpDQkI0QkVSUk9SOnhzZDpDQi5CNEIuRVJST1IiPjxDb2RlPkVYQ19HQVRFV0FZX0I0Ql9TQ0hFTUFfVkFMSURBVElPTl9FUlJPUjwvQ29kZT48TWVzc2FnZT5FcnJvciBzY2hlbWEgdmFsaWRhdGlvbjwvTWVzc2FnZT48L0NCLkI0Qi5FUlJPUj4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_RESP</Type><Content Id="4983a141-f7be-437d-8f01-76153db16136">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5NzU5Njg8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDEtMjRUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+R08zMFBTTEc4Nko4Vk5GNTwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+QUNDUDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjFlNzI2Yjg2MjNjMjQ0NTRiYTc1YzA3NzZkMzY5Y2ZiPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPkdTMThOOE41VEJSM08wPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD4xZTcyNmI4NjIzYzI0NDU0YmE3NWMwNzc2ZDM2OWNmYjwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5BQ0NQPC9UeFN0cz48L1R4SW5mQW5kU3RzPjwvT3JnbmxQbXRJbmZBbmRTdHM+PC9Dc3RtclBtdFN0c1JwdD48L0RvY3VtZW50Pg==</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_EXEC</Type><Content Id="76fc1f3a-d1a4-4902-9677-6fdcad578779">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5NzU5NzE8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDEtMjRUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+R08zMFBTTEc4Nko4Vk5GNTwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+QUNTUDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjFlNzI2Yjg2MjNjMjQ0NTRiYTc1YzA3NzZkMzY5Y2ZiPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPkdTMThOOE41VEJSM08wPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD4xZTcyNmI4NjIzYzI0NDU0YmE3NWMwNzc2ZDM2OWNmYjwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5BQ1NQPC9UeFN0cz48L1R4SW5mQW5kU3RzPjwvT3JnbmxQbXRJbmZBbmRTdHM+PC9Dc3RtclBtdFN0c1JwdD48L0RvY3VtZW50Pg==</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_RESP</Type><Content Id="403e2d34-d771-49bd-981f-1a2ee23c9f7d">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5ODA2NTY8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDItMTFUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+SUVCTlJHNVU1Vk9ISFVINDwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+UkpDVDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjg0ZmUxMmM5MDIyNzQ2YTFhMmI2N2UwOTU0ZWM1NDAwPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPkFCSDI4OVJVU1FWTUJEPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD44NGZlMTJjOTAyMjc0NmExYTJiNjdlMDk1NGVjNTQwMDwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5SSkNUPC9UeFN0cz48U3RzUnNuSW5mPjxSc24+PENkPk5BUlI8L0NkPjwvUnNuPjxBZGR0bEluZj5NYWtzxIF0xIFqYSBrb250YSBJQkFOOiBJenbEk2xpZXRpZXMga29udGEgbnVtdXJ1LjwvQWRkdGxJbmY+PC9TdHNSc25JbmY+PC9UeEluZkFuZFN0cz48L09yZ25sUG10SW5mQW5kU3RzPjwvQ3N0bXJQbXRTdHNScHQ+PC9Eb2N1bWVudD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_RESP</Type><Content Id="63fa8697-74b8-42f1-8bbd-34712cc5aebe">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5ODA2Njg8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDItMTFUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+MkRRSFZGMEREQjRJODZHTTwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+UkpDVDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjBjMjY4NmRkMmIwZjQyMmY5ODYxMzRlZmYwY2E5OTliPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPjFMVkZLQzA3MFVOMTdBPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD4wYzI2ODZkZDJiMGY0MjJmOTg2MTM0ZWZmMGNhOTk5YjwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5SSkNUPC9UeFN0cz48U3RzUnNuSW5mPjxSc24+PENkPk5BUlI8L0NkPjwvUnNuPjxBZGR0bEluZj5NYWtzxIF0xIFqYSBrb250YSBJQkFOOiBJenbEk2xpZXRpZXMga29udGEgbnVtdXJ1LjwvQWRkdGxJbmY+PC9TdHNSc25JbmY+PC9UeEluZkFuZFN0cz48L09yZ25sUG10SW5mQW5kU3RzPjwvQ3N0bXJQbXRTdHNScHQ+PC9Eb2N1bWVudD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_RESP</Type><Content Id="1e6e6f11-7a62-4a7b-b4e4-d58d6bab105a">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5ODA2NzI8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDItMTFUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+UFFKRkpDRUQ5Qk4zSDBPMDwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+UkpDVDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPmM1OGFiODRhYzY3MzQ5ZjJhNTdjOTZiNjY3ZjI5OTk0PC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPjNUVUFWT0REQjBOVDFKPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD5jNThhYjg0YWM2NzM0OWYyYTU3Yzk2YjY2N2YyOTk5NDwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5SSkNUPC9UeFN0cz48U3RzUnNuSW5mPjxSc24+PENkPk5BUlI8L0NkPjwvUnNuPjxBZGR0bEluZj5NYWtzxIF0xIFqYSBrb250YSBJQkFOOiBJenbEk2xpZXRpZXMga29udGEgbnVtdXJ1LjwvQWRkdGxJbmY+PC9TdHNSc25JbmY+PC9UeEluZkFuZFN0cz48L09yZ25sUG10SW5mQW5kU3RzPjwvQ3N0bXJQbXRTdHNScHQ+PC9Eb2N1bWVudD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_RESP</Type><Content Id="ca887cc0-da2c-4bf7-8547-544e991c8062">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5ODA2NzY8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDItMTFUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+OUc1TlNQU1FIUThIR0FSUzwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+QUNDUDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjE3ZDI3MzMzMTQ3ODQxNmQ5ZmJlYzI0NzdmNTViMDBlPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPlJPTUNNR0NNVjVHU0FWPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD4xN2QyNzMzMzE0Nzg0MTZkOWZiZWMyNDc3ZjU1YjAwZTwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5BQ0NQPC9UeFN0cz48L1R4SW5mQW5kU3RzPjwvT3JnbmxQbXRJbmZBbmRTdHM+PC9Dc3RtclBtdFN0c1JwdD48L0RvY3VtZW50Pg==</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PMT_EXEC</Type><Content Id="abed84cd-1a34-412a-8522-268da3a9b14e">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxEb2N1bWVudCB4bWxucz0idXJuOmlzbzpzdGQ6aXNvOjIwMDIyOnRlY2g6eHNkOnBhaW4uMDAyLjAwMS4wMyI+PENzdG1yUG10U3RzUnB0PjxHcnBIZHI+PE1zZ0lkPkdXMDAwMDAwMzI5ODA2Nzk8L01zZ0lkPjxDcmVEdFRtPjIwMjItMDItMTFUMDA6MDA6MDA8L0NyZUR0VG0+PEluaXRnUHR5PjxJZD48T3JnSWQ+PEJJQ09yQkVJPlBBUlhMVjIyPC9CSUNPckJFST48L09yZ0lkPjwvSWQ+PC9Jbml0Z1B0eT48L0dycEhkcj48T3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sTXNnSWQ+OUc1TlNQU1FIUThIR0FSUzwvT3JnbmxNc2dJZD48T3JnbmxNc2dObUlkPnBhaW4uMDAxLjAwMS4wMzwvT3JnbmxNc2dObUlkPjxHcnBTdHM+QUNTUDwvR3JwU3RzPjwvT3JnbmxHcnBJbmZBbmRTdHM+PE9yZ25sUG10SW5mQW5kU3RzPjxPcmdubFBtdEluZklkPjE3ZDI3MzMzMTQ3ODQxNmQ5ZmJlYzI0NzdmNTViMDBlPC9PcmdubFBtdEluZklkPjxUeEluZkFuZFN0cz48T3JnbmxJbnN0cklkPlJPTUNNR0NNVjVHU0FWPC9PcmdubEluc3RySWQ+PE9yZ25sRW5kVG9FbmRJZD4xN2QyNzMzMzE0Nzg0MTZkOWZiZWMyNDc3ZjU1YjAwZTwvT3JnbmxFbmRUb0VuZElkPjxUeFN0cz5BQ1NQPC9UeFN0cz48L1R4SW5mQW5kU3RzPjwvT3JnbmxQbXRJbmZBbmRTdHM+PC9Dc3RtclBtdFN0c1JwdD48L0RvY3VtZW50Pg==</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_ERROR</Type><Content Id="ab97695b-9bdd-4476-a2c9-6945c1297159">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuRVJST1IgeG1sbnM9InVybjpDQkI0QkVSUk9SOnhzZDpDQi5CNEIuRVJST1IiPjxDb2RlPkVYQ19HQVRFV0FZX0I0Ql9TQ0hFTUFfVkFMSURBVElPTl9FUlJPUjwvQ29kZT48TWVzc2FnZT5FcnJvciBzY2hlbWEgdmFsaWRhdGlvbjwvTWVzc2FnZT48L0NCLkI0Qi5FUlJPUj4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="252af2c8-d9f8-4e08-9f51-bcf23d7da55a">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="923b95b7-d80f-4a70-a162-8f6f866177a4">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="9c80fd1a-aa2a-4f75-8eba-d8133901df61">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="ca97ed60-14c2-4f8e-86f7-fb22bcf12b14">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="e04742d8-fdd7-4f18-81f2-2487f928afdf">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.APP.REQ xmlns="urn:CBB4BAPPREQ:xsd:CB.B4B.APP.REQ"><Type>CB_B4B_PING_RESP</Type><Content Id="066a5eed-12b2-4e38-85ca-b4b241af6da7">PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiIHN0YW5kYWxvbmU9InllcyI/PjxDQi5CNEIuUElORy5SRVNQIHhtbG5zPSJ1cm46Q0JCNEJQSU5HUkVTUDp4c2Q6Q0IuQjRCLlBJTkcuUkVTUCI+PFZhbHVlPlBpbmc8L1ZhbHVlPjwvQ0IuQjRCLlBJTkcuUkVTUD4=</Content></CB.B4B.APP.REQ>
And now, you also need to do the second decoding step which is for the value of SOAP XML <Content>...</Content>
tag.
Extract XML Content Tag Value With Regex
Okay, by this point you already have some kind of response – the response variable (which was base64 decoded one time) and it is an XML scheme.
The same as with the manual steps above, you need to find a way to extract only the value of
tags.<Content>...</Content>
A slightly different approach here with the regex, since you’re already working with a single line (each for loop iteration is a single line – a single string object), there’s no need to use re.findall
approach you used the first time.
Instead, I’d use re.search which is meant to be used to return a match object.
And the regex pattern here is similar, but now it’s tweaked for this specific XML tag.
regex_pattern = r'<Content Id=\".*?\">(.*?)</Content>'
Like I’ve said before, to have a better understanding of regex patterns, you have to study them.
Another option is to contact me and maybe I can help you out not just with regex, but also with becoming a Python developer and getting hired as a developer.
See more details on how to contact me below this post.
But just to give you an idea of what’s going on with the pattern and why I choose to use this specific pattern, I’m going to share a screenshot from the Python regex101 tool.
And here’s the whole code example for XML SOAP response parsing with Python. As you can see we’re moving forward step by step and only the last part of the code block has changed. Let’s keep going and finalize it.
import re
import typing
import base64
import binascii
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
responses = []
for data_tag in data_tags:
res_base64: str = (
data_tag
.replace('<data>', '')
.replace('</data>', '')
)
try:
response: str = (
base64
.b64decode(res_base64)
.decode('utf-8')
)
except binascii.Error:
continue
content_tag_match: re.Match = re.search(
r'<Content Id=\".*?\">(.*?)</Content>',
response,
re.DOTALL
)
if not content_tag_match:
continue
print(content_tag_match)
The output, at this point, should be a bunch of regex match objects with some kind of identification.
<re.Match object; span=(187, 456), match='<Content Id="a53e98e4-0197-4513-be6d-49836e406aaa>
<re.Match object; span=(139, 492), match='<Content Id="7a36dfd4-010e-4c54-8d08-a2e59946a22c>
<re.Match object; span=(139, 492), match='<Content Id="190b9604-e852-46e1-9f73-cf089cc0c2b4>
<re.Match object; span=(142, 1175), match='<Content Id="4983a141-f7be-437d-8f01-76153db16136>
<re.Match object; span=(142, 1175), match='<Content Id="76fc1f3a-d1a4-4902-9677-6fdcad578779>
<re.Match object; span=(142, 1331), match='<Content Id="403e2d34-d771-49bd-981f-1a2ee23c9f7d>
<re.Match object; span=(142, 1331), match='<Content Id="63fa8697-74b8-42f1-8bbd-34712cc5aebe>
<re.Match object; span=(142, 1331), match='<Content Id="1e6e6f11-7a62-4a7b-b4e4-d58d6bab105a>
<re.Match object; span=(142, 1175), match='<Content Id="ca887cc0-da2c-4bf7-8547-544e991c8062>
<re.Match object; span=(142, 1175), match='<Content Id="abed84cd-1a34-412a-8522-268da3a9b14e>
<re.Match object; span=(139, 492), match='<Content Id="ab97695b-9bdd-4476-a2c9-6945c1297159>
<re.Match object; span=(143, 416), match='<Content Id="252af2c8-d9f8-4e08-9f51-bcf23d7da55a>
<re.Match object; span=(143, 416), match='<Content Id="923b95b7-d80f-4a70-a162-8f6f866177a4>
<re.Match object; span=(143, 416), match='<Content Id="9c80fd1a-aa2a-4f75-8eba-d8133901df61>
<re.Match object; span=(143, 416), match='<Content Id="ca97ed60-14c2-4f8e-86f7-fb22bcf12b14>
<re.Match object; span=(143, 416), match='<Content Id="e04742d8-fdd7-4f18-81f2-2487f928afdf>
<re.Match object; span=(143, 416), match='<Content Id="066a5eed-12b2-4e38-85ca-b4b241af6da7>
Decode Base64 Response With Python (The Second Time)
Again, a very similar process to what you have already experienced a bit above, now that you have the access to content_tag_match
variable, you need to find a way to extract the value.
In Python regex, when you use re.search
method and also the regex pattern includes ( )
it means there must be a way to access each group.
regex_pattern = r'<Content Id=\".*?\">(.*?)</Content>'
In other words, if you use ( )
inside your regex pattern, you can group different values you want to extract.

To access a specific match group in Python regex, you have to apply .group(group_id)
on a Python regex match object.
See line content_tag_b64: str = content_tag_match.group(1)
import re
import typing
import base64
import binascii
stdout_file_path = './data/stdout_example.txt'
with open(stdout_file_path, 'r') as f:
stdout = f.read()
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
responses = []
for data_tag in data_tags:
res_base64: str = (
data_tag
.replace('<data>', '')
.replace('</data>', '')
)
try:
response: str = (
base64
.b64decode(res_base64)
.decode('utf-8')
)
except binascii.Error:
continue
content_tag_match: re.Match = re.search(
r'<Content Id=\".*?\">(.*?)</Content>',
response,
re.DOTALL
)
if not content_tag_match:
continue
content_tag_b64: str = content_tag_match.group(1)
try:
content: str = (
base64
.b64decode(content_tag_b64)
.decode('utf-8')
)
except binascii.Error:
continue
responses.append(content)
for res in responses:
print(res)
And the end result is a fully decoded SOAP XML response which then can be processed using a different Python XML package. (Not going to go into that in this post, but might do it later – if you’re interested to see such solution, comment below the post)
<?xml version="1.0" encoding="UTF-8" standalone="no"?><CB.B4B.PING.REQ xmlns="urn:CBB4BPINGREQ:xsd:CB.B4B.PING.REQ">
<Value>Ping</Value>
</CB.B4B.PING.REQ>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.ERROR xmlns="urn:CBB4BERROR:xsd:CB.B4B.ERROR"><Code>EXC_GATEWAY_B4B_SCHEMA_VALIDATION_ERROR</Code><Message>Error schema validation</Message></CB.B4B.ERROR>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.ERROR xmlns="urn:CBB4BERROR:xsd:CB.B4B.ERROR"><Code>EXC_GATEWAY_B4B_SCHEMA_VALIDATION_ERROR</Code><Message>Error schema validation</Message></CB.B4B.ERROR>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032975968</MsgId><CreDtTm>2022-01-24T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>GO30PSLG86J8VNF5</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>ACCP</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>1e726b8623c24454ba75c0776d369cfb</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>GS18N8N5TBR3O0</OrgnlInstrId><OrgnlEndToEndId>1e726b8623c24454ba75c0776d369cfb</OrgnlEndToEndId><TxSts>ACCP</TxSts></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032975971</MsgId><CreDtTm>2022-01-24T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>GO30PSLG86J8VNF5</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>ACSP</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>1e726b8623c24454ba75c0776d369cfb</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>GS18N8N5TBR3O0</OrgnlInstrId><OrgnlEndToEndId>1e726b8623c24454ba75c0776d369cfb</OrgnlEndToEndId><TxSts>ACSP</TxSts></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032980656</MsgId><CreDtTm>2022-02-11T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>IEBNRG5U5VOHHUH4</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>RJCT</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>84fe12c9022746a1a2b67e0954ec5400</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>ABH289RUSQVMBD</OrgnlInstrId><OrgnlEndToEndId>84fe12c9022746a1a2b67e0954ec5400</OrgnlEndToEndId><TxSts>RJCT</TxSts><StsRsnInf><Rsn><Cd>NARR</Cd></Rsn><AddtlInf>Maksātāja konta IBAN: Izvēlieties konta numuru.</AddtlInf></StsRsnInf></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032980668</MsgId><CreDtTm>2022-02-11T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>2DQHVF0DDB4I86GM</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>RJCT</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>0c2686dd2b0f422f986134eff0ca999b</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>1LVFKC070UN17A</OrgnlInstrId><OrgnlEndToEndId>0c2686dd2b0f422f986134eff0ca999b</OrgnlEndToEndId><TxSts>RJCT</TxSts><StsRsnInf><Rsn><Cd>NARR</Cd></Rsn><AddtlInf>Maksātāja konta IBAN: Izvēlieties konta numuru.</AddtlInf></StsRsnInf></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032980672</MsgId><CreDtTm>2022-02-11T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>PQJFJCED9BN3H0O0</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>RJCT</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>c58ab84ac67349f2a57c96b667f29994</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>3TUAVODDB0NT1J</OrgnlInstrId><OrgnlEndToEndId>c58ab84ac67349f2a57c96b667f29994</OrgnlEndToEndId><TxSts>RJCT</TxSts><StsRsnInf><Rsn><Cd>NARR</Cd></Rsn><AddtlInf>Maksātāja konta IBAN: Izvēlieties konta numuru.</AddtlInf></StsRsnInf></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032980676</MsgId><CreDtTm>2022-02-11T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>9G5NSPSQHQ8HGARS</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>ACCP</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>17d273331478416d9fbec2477f55b00e</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>ROMCMGCMV5GSAV</OrgnlInstrId><OrgnlEndToEndId>17d273331478416d9fbec2477f55b00e</OrgnlEndToEndId><TxSts>ACCP</TxSts></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><Document xmlns="urn:iso:std:iso:20022:tech:xsd:pain.002.001.03"><CstmrPmtStsRpt><GrpHdr><MsgId>GW00000032980679</MsgId><CreDtTm>2022-02-11T00:00:00</CreDtTm><InitgPty><Id><OrgId><BICOrBEI>PARXLV22</BICOrBEI></OrgId></Id></InitgPty></GrpHdr><OrgnlGrpInfAndSts><OrgnlMsgId>9G5NSPSQHQ8HGARS</OrgnlMsgId><OrgnlMsgNmId>pain.001.001.03</OrgnlMsgNmId><GrpSts>ACSP</GrpSts></OrgnlGrpInfAndSts><OrgnlPmtInfAndSts><OrgnlPmtInfId>17d273331478416d9fbec2477f55b00e</OrgnlPmtInfId><TxInfAndSts><OrgnlInstrId>ROMCMGCMV5GSAV</OrgnlInstrId><OrgnlEndToEndId>17d273331478416d9fbec2477f55b00e</OrgnlEndToEndId><TxSts>ACSP</TxSts></TxInfAndSts></OrgnlPmtInfAndSts></CstmrPmtStsRpt></Document>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.ERROR xmlns="urn:CBB4BERROR:xsd:CB.B4B.ERROR"><Code>EXC_GATEWAY_B4B_SCHEMA_VALIDATION_ERROR</Code><Message>Error schema validation</Message></CB.B4B.ERROR>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><CB.B4B.PING.RESP xmlns="urn:CBB4BPINGRESP:xsd:CB.B4B.PING.RESP"><Value>Ping</Value></CB.B4B.PING.RESP>
Create A Function (Final Result)
Finally, I’d recommend moving everything into a separate function and calling it from a specific place in your project.
That’s how I actually did it in the end.
Comment below if you have any questions about the end result and I’ll get back to you as soon as I can.
import base64
import binascii
import re
import typing
def get_responses(stdout: str) -> typing.List[str]:
"""
Collect all <data> </data> tags from stdout, decode each data tag
and return a list of XML responses
"""
data_tags: typing.List[str] = re.findall(
r'<data\b[^>]*>(.*?)</data>',
stdout,
re.DOTALL
)
responses = []
for data_tag in data_tags:
res_base64: str = (
data_tag
.replace('<data>', '')
.replace('</data>', '')
)
try:
response: str = (
base64
.b64decode(res_base64)
.decode('utf-8')
)
except binascii.Error:
continue
content_tag_match: re.Match = re.search(
r'<Content Id=\".*?\">(.*?)</Content>',
response,
re.DOTALL
)
if not content_tag_match:
continue
content_tag_b64: str = content_tag_match.group(1)
try:
content: str = (
base64
.b64decode(content_tag_b64)
.decode('utf-8')
)
except binascii.Error:
continue
responses.append(content)
return responses
Conclusion
And this is how you can deal with parsing a large SOAP XML response in Python
So when you’re reading this post and want to learn more about Python and Regex…
It should spark at least a little fire in you 🔥
That’s how I started and that’s how you can decide to go deeper and learn more about Python
If this sounds like you…
And you want to become a Python Django developer
Start your career as a Python Django developer by writing solid software code
Maybe even working on payment integrations yourself
…then book a free consulting call with me personally!
There’s information below about how you can reach out to me.
Follow the steps below, contact me, and will probably jump on a free call to discuss your situation
I’ll see if there’s anything I can do to help you become a Python Django developer.
Talk to you soon!
Leave a Reply
You must be logged in to post a comment.