【发布时间】:2020-01-01 01:47:15
【问题描述】:
将 csv 读取到数据框,然后使用 lxml 库将其转换为 xml
这是我第一次处理 xml,似乎有部分成功。任何帮助将不胜感激。
用于创建数据框的CSV文件:
Parent,Element,Text,Attribute
,TXLife,"
",{'Version': '2.25.00'}
TXLife,UserAuthRequest,"
",{}
UserAuthRequest,UserLoginName,*****,{}
UserAuthRequest,UserPswd,"
",{}
UserPswd,CryptType,None,{}
UserPswd,Pswd,****,{}
TXLife,TXLifeRequest,"
",{'PrimaryObjectID': 'Policy_1'}
TXLifeRequest,TransRefGUID,706D67C1-CC4D-11CF-91FB444554540000,{}
TXLifeRequest,TransType,Holding Change,{'tc': '502'}
TXLifeRequest,TransExeDate,2006-11-19,{}
TXLifeRequest,TransExeTime,13:15:33-07:00,{}
TXLifeRequest,ChangeSubType,"
",{}
ChangeSubType,ChangeTC,Change Participant,{'tc': '9'}
TXLifeRequest,OLifE,"
",{}
OLifE,Holding,"
",{'id': 'Policy_1'}
Holding,HoldingTypeCode,Policy,{'tc': '2'}
Holding,Policy,"
",{}
Policy,PolNumber,1234567,{}
Policy,LineOfBusiness,Annuity,{'tc': '2'}
Policy,Annuity,,{}
OLifE,Party,"
",{'id': 'Beneficiary_1'}
Party,PartyTypeCode,Organization,{'tc': '2'}
Party,FullName,The Smith Trust,{}
Party,Organization,"
",{}
Organization,OrgForm,Trust,{'tc': '16'}
Organization,DBA,The Smith Trust,{}
OLifE,Relation,"
","{'id': 'Relation_1', 'OriginatingObjectID': 'Policy_1', 'RelatedObjectID': 'Beneficiary_1'}"
Relation,OriginatingObjectType,Holding,{'tc': '4'}
Relation,RelatedObjectType,Party,{'tc': '6'}
Relation,RelationRoleCode,Primary Beneficiary,{'tc': '34'}
Relation,BeneficiaryDesignation,Named,{'tc': '1'}
import lxml.etree as etree
import pandas as pd
import json
# Read the csv file
dfc = pd.read_csv('test_data_txlife.csv') .fillna('NA')
# # Remove rows with comments
# dfc = dfc[~dfc['Element'].str.contains("<cyfunction")].fillna('')
dfc['Attribute'] = dfc['Attribute'].apply(lambda x: x.replace("'", '"'))
# Add the root element for xml
root = etree.Element(dfc['Element'][0])
tree = root.getroottree()
for prnt, elem, txt, attr in dfc[['Parent', 'Element', 'Text', 'Attribute']][1:].values:
# Convert attributes to json (dictionary)
attrib = json.loads(attr)
# list(root) = root.getchildren()
children = [item for item in str(list(root)).split(' ')]
rootstring = str(root).split(' ')[1]
# If the parent is root then add the element as child (appaers to work?)
if prnt == str(root).split(' ')[1]:
parent = etree.SubElement(root, elem)
# If the parent is not root but is one of its children then add the elements to the parent
elif not prnt == rootstring and prnt in children:
child = etree.SubElement(parent, elem, attrib).text = txt
# # If the parent is not in root's descendents then add the childern to the parents
elif not prnt in [str(item).split(' ') for item in root.iterdescendants()]:
child = etree.SubElement(parent, elem, attrib).text = txt
print(etree.tostring(tree, pretty_print=True).decode())
实际结果:
<TXLife> <UserAuthRequest> <UserLoginName>*****</UserLoginName> <UserPswd> </UserPswd> <CryptType>None</CryptType> <Pswd>xxxxxx</Pswd> </UserAuthRequest> <TXLifeRequest> <TransRefGUID>706D67C1-CC4D-11CF-91FB444554540000</TransRefGUID> <TransType tc="502">Holding Change</TransType> <TransExeDate>11/19/2006</TransExeDate> <TransExeTime>13:15:33-07:00</TransExeTime> <ChangeSubType> </ChangeSubType> <ChangeTC tc="9">Change Participant</ChangeTC> <OLifE> </OLifE> <Holding id="Policy_1"> </Holding> <HoldingTypeCode tc="2">Policy</HoldingTypeCode> <Policy> </Policy> <PolNumber>1234567</PolNumber> <LineOfBusiness tc="2">Annuity</LineOfBusiness> <Annuity>NA</Annuity> <Party id="Beneficiary_1"> </Party> <PartyTypeCode tc="2">Organization</PartyTypeCode> <FullName>The Smith Trust</FullName> <Organization> </Organization> <OrgForm tc="16">Trust</OrgForm> <DBA>The Smith Trust</DBA> <Relation OriginatingObjectID="Policy_1" RelatedObjectID="Beneficiary_1" id="Relation_1"> </Relation> <OriginatingObjectType tc="4">Holding</OriginatingObjectType> <RelatedObjectType tc="6">Party</RelatedObjectType> <RelationRoleCode tc="34">Primary Beneficiary</RelationRoleCode> <BeneficiaryDesignation tc="1">Named</BeneficiaryDesignation> </TXLifeRequest> </TXLife>
期望的结果:
<TXLife Version="2.25.00"> <UserAuthRequest> <UserLoginName>*****</UserLoginName> <UserPswd> <CryptType>None</CryptType> <Pswd>****</Pswd> </UserPswd> </UserAuthRequest> <TXLifeRequest PrimaryObjectID="Policy_1"> <TransRefGUID>706D67C1-CC4D-11CF-91FB444554540000</TransRefGUID> <TransType tc="502">Holding Change</TransType> <TransExeDate>2006-11-19</TransExeDate> <TransExeTime>13:15:33-07:00</TransExeTime> <ChangeSubType> <ChangeTC tc="9">Change Participant</ChangeTC> </ChangeSubType> <OLifE> <Holding id="Policy_1"> <HoldingTypeCode tc="2">Policy</HoldingTypeCode> <Policy> <PolNumber>1234567</PolNumber> <LineOfBusiness tc="2">Annuity</LineOfBusiness> <Annuity></Annuity> </Policy> </Holding> <Party id="Beneficiary_1"> <PartyTypeCode tc="2">Organization</PartyTypeCode> <FullName>The Smith Trust</FullName> <Organization> <OrgForm tc="16">Trust</OrgForm> <DBA>The Smith Trust</DBA> </Organization> </Party> <Relation id="Relation_1" OriginatingObjectID="Policy_1" RelatedObjectID="Beneficiary_1"> <OriginatingObjectType tc="4">Holding</OriginatingObjectType> <RelatedObjectType tc="6">Party</RelatedObjectType> <RelationRoleCode tc="34">Primary Beneficiary</RelationRoleCode> <BeneficiaryDesignation tc="1">Named</BeneficiaryDesignation> </Relation> </OLifE> </TXLifeRequest> </TXLife>
我怎样才能得到如上所示的分层结果?
【问题讨论】: