遍历XML中的特定子节点并使用Python保存到CSV

时间:2019-01-29 22:09:18

标签: python xml csv

我已经通过了一堆类似的问题看,并没有看到解决了这个具体的答案。我以前没有在python中使用XML文件,而且时间紧迫,所以我可能只是忽略了显而易见的内容。我有一大堆的XML文件,我需要随意在两个值,对于文件中的每个供应商记录。我需要保存那些在CSV。

我有一些代码,在捉弄超过我期待...

/Users/davea/Documents/workspac

在XML有一堆重复PROVIDER_GROUP的和在所有的提供者组的每个提供商我需要提供者的PROV_IDENTIFIER和TAXONOMY_CODE。

import xml.etree.ElementTree as ET
import csv

tree = ET.parse('xml/HSP-FullOutOfAreaSite03-DEC.xml')
root = tree.getroot()

for PROVIDER in root.iter('PROVIDER'):
    for PROV_IDENTIFIER in PROVIDER:
        print(PROV_IDENTIFIER.text)
    for TAXONOMY_CODE in PROVIDER:
        print(TAXONOMY_CODE.text)

我需要一个看起来像CSV的

<PROVIDER_GROUP>
    <MASTER_GROUP_CODE>345093845</MASTER_GROUP_CODE>
    <TAX_ID>3095</TAX_ID>
    <GROUPNUMBER>16</GROUPNUMBER>
    <SITECOUNT>1</SITECOUNT>
    <CONTRACTS>
      <CONTRACT>
        <EFF_DATE>2002-01-01</EFF_DATE>
      </CONTRACT>
    </CONTRACTS>
    <PROVIDER_SITES>
      <PROVIDER_SITE>
        <PROV_MASTER_ID>18583783745</PROV_MASTER_ID>
        <MASTER_GROUP_CODE>584293845</MASTER_GROUP_CODE>
        <PROVIDERS>

          <PROVIDER>
            <PROVNO>123456</PROVNO>
            <NAME_FIRST>John</NAME_FIRST>
            <NAME_LAST>Doe</NAME_LAST>
            <NAME_CREDENTIAL>DDD</NAME_CREDENTIAL>
            <GENDER>M</GENDER>
            <PROV_IDENTIFIER>3459832385</PROV_IDENTIFIER>
            <TAXONOMIES>
              <TAXONOMY>
                <TAXONOMY_CODE>23498R98239X</TAXONOMY_CODE>
              </TAXONOMY>
            </TAXONOMIES>
            <HOSPRELATIONS>
              <HOSP>
                <NPI>1366896300</NPI>
              </HOSP>
            </HOSPRELATIONS>
          </PROVIDER>

         <PROVIDER>
            <PROVNO>123454</PROVNO>
            <NAME_FIRST>Jane</NAME_FIRST>
            <NAME_LAST>Doe</NAME_LAST>
            <NAME_CREDENTIAL>DDD</NAME_CREDENTIAL>
            <GENDER>F</GENDER>
            <PROV_IDENTIFIER>3945092358</PROV_IDENTIFIER>
            <TAXONOMIES>
              <TAXONOMY>
                <TAXONOMY_CODE>55598R98239X</TAXONOMY_CODE>
              </TAXONOMY>
            </TAXONOMIES>
            <HOSPRELATIONS>
              <HOSP>
                <NPI>34598345030</NPI>
              </HOSP>
            </HOSPRELATIONS>
          </PROVIDER>

        </PROVIDERS>
      </PROVIDER_SITE>
    </PROVIDER_SITES>
  </PROVIDER_GROUP>

  <PROVIDER_GROUP>
    <PROVIDER_SITES>
      <PROVIDER_SITE>
        <PROVIDERS>
         <!-- MORE PROVIDERS -->
        </PROVIDERS>
      </PROVIDER_SITE>
    </PROVIDER_SITES>
  </PROVIDER_GROUP>

2 个答案:

答案 0 :(得分:1)

这是一个简单的示例,因此您可以了解如何进行:

from xml.etree import ElementTree as ET
tree = ET.parse('xml/HSP-FullOutOfAreaSite03-DEC.xml')
providers = tree.findall(".//PROVIDERS/PROVIDER")
agg = [
    (p.find('./PROV_IDENTIFIER').text,
        [t.text for t in p.findall(".//TAXONOMY_CODE")]) for p in providers]

如果对您的XML示例运行此操作,您将获得

[('3459832385', ['23498R98239X']), ('3945092358', ['55598R98239X'])]

元组中的第一个元素将具有PROV_IDENTIFIER,第二个元素将是所有嵌套TAXONOMY_CODE元素的列表。

答案 1 :(得分:1)

您可以将XML放入bs4中,并像这样获取它们:

from bs4 import BeautifulSoup
import pandas as pd

with open('xml/HSP-FullOutOfAreaSite03-DEC.xml', 'r') as f:
    soup = BeautifulSoup(f.read(), 'lxml')

# Get the data you want
df = pd.DataFrame(list(zip(
  [el.text for el in soup.find_all('prov_identifier')],
  [el.text for el in soup.find_all('taxonomy_code')]
)), columns=['PROV_IDENTIFIER', 'TAXONOMY_CODE'])

# Dump to csv
df.to_csv('out.csv', index=False)