Reputation: 13
My Python scripts converts the xml to json. But the array of an for e.g address is converted to an object which I don't want. I want it to remain as array only. Below is my python script along with input xml and output json I am expecting. Thanks and appreciate your help In our application we take xml as an input string in a variable and also output json in a variable and test and compare the xml with the json
import json
import xmltodict
xml = xmltodict.parse(inputxml)
CustomerCreateandUpdate = xml['SyncCustomerCreateandUpdate']['DataArea']['CustomerCreateandUpdate']
outputjson = json.dumps(CustomerCreateandUpdate)
<?xml version="1.0" encoding="UTF-8"?>
<SyncCustomerCreateandUpdate xmlns="http://schema.infor.com/InforOAGIS/2"
xmlns:xs="http://www.w3.org/2001/XMLSchema" languageCode="EN" releaseID="9.2"
systemEnvironmentCode="Production" versionID="2.11.0">
<ApplicationArea>
<Sender>
<LogicalID schemeVersionID="16.0.0.015">lid://infor.m3.m3</LogicalID>
<ComponentID schemeVersionID="16.0.0.20201209170022">M3BE</ComponentID>
<ConfirmationCode>OnError</ConfirmationCode>
</Sender>
<CreationDateTime>2021-03-04T12:33:12.487Z</CreationDateTime>
<BODID>1bb40f80-8039-4264-b903-fa58ca2d3a9a</BODID>
</ApplicationArea>
<DataArea>
<Sync>
<AccountingEntityID>001_090</AccountingEntityID>
<ActionCriteria>
<ActionExpression actionCode="Add"/>
</ActionCriteria>
</Sync>
<CustomerCreateandUpdate>
<customerName>TEST1838</customerName>
<customerStatus>Test5</customerStatus>
<addresses>
<addressLine1>test</addressLine1>
<addressLine2>test</addressLine2>
<addressLine3>test</addressLine3>
<addressLine4>test</addressLine4>
<postalCode>2200</postalCode>
<city>Herentals</city>
<stateCode>test</stateCode>
<countryCode>BE</countryCode>
</addresses>
<phones>
<phoneNumber>test</phoneNumber>
</phones>
<faxNumber>999</faxNumber>
<contacts>
<firstName>test</firstName>
<lastName>test</lastName>
<emailAddress>test</emailAddress>
<mobilePhone>test</mobilePhone>
</contacts>
<emails>
<emailType>TEST</emailType>
<emailAddress>Test</emailAddress>
</emails>
<references>test</references>
<freeFields>
<number>0</number>
<content>test</content>
</freeFields>
<searchKey>test</searchKey>
<customerType>test</customerType>
<description>test</description>
<serviceArea>test</serviceArea>
<lelyCenter>test</lelyCenter>
<lspId>test</lspId>
<m3Id>test</m3Id>
<createdById>test</createdById>
<lastModifiedById>test</lastModifiedById>
<lastModifiedDate>test</lastModifiedDate>
<vatNumber>test</vatNumber>
</CustomerCreateandUpdate>
</DataArea>
Json expected output:
{
"customerName": "",
"customerStatus": "",
"addresses": [
{
"addressLine1": "",
"addressLine2": "",
"addressLine3": "",
"addressLine4": "",
"postalCode": "",
"city": "",
"stateCode": "",
"countryCode": ""
}
],
"phones": [
{
"phoneNumber": ""
}
],
"faxNumber": "",
"contacts": [
{
"firstName": "",
"lastName": "",
"emailAddress": "",
"mobilePhone": ""
}
],
"emails": [
{
"emailType": "",
"emailAddress": ""
}
],
"references": [
""
],
"freeFields": [
{
"number": 0,
"content": ""
}
],
"language": "",
"searchKey": "",
"customerType": 0,
"description": "",
"lelyCenter": "",
"lspId": "",
"m3Id": "",
"createdById": "",
"lastModifiedById": "",
"lastModifiedDate": "",
"vatNumber": ""
}
Upvotes: 0
Views: 623
Reputation: 1468
The way address data is described in your xml drives xmltodict
to represent it as a json object. First, address data sould be encapsulated into a dedicated container like so (How to represent list data in XML):
<addresses>
<address>
<addressLine1>test</addressLine1>
<addressLine2>test</addressLine2>
<addressLine3>test</addressLine3>
<addressLine4>test</addressLine4>
<postalCode>2200</postalCode>
<city>Herentals</city>
<stateCode>test</stateCode>
<countryCode>BE</countryCode>
</address>
</addresses>
But obviously this structure is not enough for xmltodict
to detect it as a list of items. It needs to browse at least to times the same tag to understand it as an iterable. So if your address list has only one element you have to put a void address tag:
<addresses>
<address>
<addressLine1>test</addressLine1>
<addressLine2>test</addressLine2>
<addressLine3>test</addressLine3>
<addressLine4>test</addressLine4>
<postalCode>2200</postalCode>
<city>Herentals</city>
<stateCode>test</stateCode>
<countryCode>BE</countryCode>
</address>
<address></address>
</addresses>
With the new version of xmltodict
it is not necessary to add a void tag. Just use the argument force_list={<tag name>} in the parse method (xmltodict does not return a list for one element):
xmltodict.parse(xml_data, force_list={"addresses"})
Upvotes: 1