繁体   English   中英

python xml 和 csv 提取

[英]python xml and csv extract

我有 2 组文件 - (1) CSV 文件(主文件)(2)XML 文件。

CSV 文件 -

emp_id
1
2
3
4

XML 文件 -

<employee>
    <emp id="1" />
    <emp id="2" active="yes">
        <tag k="age" v="55" />
    </emp>
    <emp id="3" active="yes">
        <tag k="name" v="scott" />
    </emp>
    <emp id="4" active="no">
        <tag k="address" v="Texas" />
    </emp>
    <emp id="5" gender="male"/>
    <emp id="8" />
    <emp id="9" />
    <emp id="10" />
    <emp id="11" />
</employee>

我的目标是有一个 csv 文件,其中 csv 文件中的 emp_id 与 XML 文件匹配,并且在新的 csv 文件中只创建匹配的 emp_id。 我需要 2 个 csv 文件,如下所示 -

第一个文件。

emp_id,active,gender
1,,
2,yes,
3,yes,
4,no,
5,,male

第二个文件。

emp_id,key,value
2,age,55
3,name,scott
4,address,Texas

我可以在 Pandas 中读取 CSV 文件,在 Python 中读取 XML 文件。 但不知道如何组合它们并从 XML 中提取键和值

任何帮助表示赞赏。

另一种方法。

from simplified_scrapy import SimplifiedDoc, utils
empIds = ['1', '2', '3', '4', '5']
# empIds = [id.strip() for id in utils.getFileLines('your csv file path')[1:]]

xml = '''<employee>
    <emp id="1" />
    <emp id="2" active="yes">
        <tag k="age" v="55" />
    </emp>
    <emp id="3" active="yes">
        <tag k="name" v="scott" />
    </emp>
    <emp id="4" active="no">
        <tag k="address" v="Texas" />
    </emp>
    <emp id="5" gender="male"/>
    <emp id="8" />
    <emp id="9" />
    <emp id="10" />
    <emp id="11" />
</employee>
'''
# xml = utils.getFileContent('your xml file path')

rows1 = [['emp_id', 'active', 'gender']]
rows2 = [['emp_id', 'key', 'value']]
doc = SimplifiedDoc(xml)
for id in empIds:
    emp = doc.select('emp#' + id)
    if emp:
        rows1.append([id, emp.get('active'), emp.get('gender')])
        tags = emp.selects('tag')
        if tags:
            for tag in tags:
                rows2.append([id, tag['k'], tag['v']])

utils.save2csv('csv1.csv', rows1, newline='')
utils.save2csv('csv2.csv', rows2, newline='')

结果 csv1:

emp_id,active,gender
1,,
2,yes,
3,yes,
4,no,
5,,male

结果 csv2:

emp_id,key,value
2,age,55
3,name,scott
4,address,Texas

首先df:读取XML并创建DataFrame

import xmltodict
with open('XmlFile.xml') as fd:
    xmlfile = xmltodict.parse(fd.read())
df_xmlfile = pd.DataFrame(xmlfile["employee"]["emp"])
df_xmlfile.columns = [col.replace("@","") for col in df_xmlfile.columns]

将 CSV 读取为 DataFrame

df_csvfile = csvfile=pd.read_csv("CsvFile.txt")

加入两个 dfs

df_first = df_csvfile.join(df_xmlfile[["active", "gender"]])

第二个 df:获取包含标签的行,解压这些行以获取键和值并创建第二个 df

df_temp = df_xmlfile[~df_xmlfile["tag"].isna()][["id", "tag"]]
df_second = pd.DataFrame({"emp_id": df_temp["id"],
              "key": [row["@k"] for row in df_temp["tag"]],
              "value": [row["@v"] for row in df_temp["tag"]]})

让我们创建第一个数据框:

# this dataframe should be read from csv in your case
df = pd.DataFrame({
    'emp_id':[1, 2, 3, 4, 5]
})

比定义 XML:

xml = '''<employee>
    <emp id="1" />
    <emp id="2" active="yes">
        <tag k="age" v="55" />
    </emp>
    <emp id="3" active="yes">
        <tag k="name" v="scott" />
    </emp>
    <emp id="4" active="no">
        <tag k="address" v="Texas" />
    </emp>
    <emp id="5" gender="male"/>
    <emp id="8" />
    <emp id="9" />
    <emp id="10" />
    <emp id="11" />
</employee>'''

从 XML 读取数据:

d = defaultdict(list)
# here we read XML from string, in your case it should be read from file
root = et.fromstring(xml)
emps = root.xpath('//employee/emp')
# iterate over elements "emp" and extract data
for emp in emps:
  # here we extract attributes id, active and gender
  d['id'].append(int(emp.get('id')))
  d['active'].append(None if emp.get('active') is None else emp.get('active'))
  d['gender'].append(None if emp.get('gender') is None else emp.get('gender'))
  # here we extract age
  age = emp.find('./tag[@k="age"]')
  d['age'].append(None if age is None else age.get('v'))
  # here we extract address
  address = emp.find('./tag[@k="address"]')
  d['address'].append(None if address is None else address.get('v'))

比从 dict 创建数据帧:

df_xml = pd.DataFrame(d)

比使用 emp_id / id 列合并数据:

df_merged = pd.merge(df, df_xml, left_on = 'emp_id', right_on='id', how = 'inner')
del df_merged['id']

df_merged.head(10)

输出:

输出

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM