【问题标题】:XML to CSV but same tags under parentXML 到 CSV 但父级下的标签相同
【发布时间】:2018-12-30 12:36:50
【问题描述】:

我有一个这样的 XML 文件,并尝试使用 xml2csv python 库将其转换为 CSV。但是有一个 图像标签破坏了一切。我想在不同的列上获取所有 标签。我怎样才能做到这一点?

谢谢,

<products>
    <product>
        <code>722</code>
        <ws_code>B515C16CRU</ws_code>
        <supplier_code>B515C16CRU</supplier_code>
        <images>
            <img_item type_name="">
            https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3378-72-B.jpg
            </img_item>
            <img_item type_name="">
            https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3379-72-B.jpg
            </img_item>
            <img_item type_name="">
            https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3380-72-B.jpg
            </img_item>
        </images>
    </product>
    .... 
</products>

【问题讨论】:

    标签: python excel xml


    【解决方案1】:

    正如您可能已经猜到的那样,问题是因为每个product 节点都有多个img_item 标签,xml2csv 不知道如何处理(而且,翻阅它的文档,似乎没有选择让它知道如何处理这些节点)。

    但是,您可以使用内置的 csv 模块轻松完成此操作。您只需要决定如何分隔不同图像的 url。在下面的示例中,我决定使用;(显然你不能使用,,除非你对列使用另一个分隔符)。

    另请注意,我对标题进行了硬编码。这可以(非常)轻松地更改,以便从 product 节点的子元素中动态检测标头。

    import csv
    import xml.etree.ElementTree as ET
    
    string = '''<products>
        <product>
            <code>722</code>
            <ws_code>B515C16CRU</ws_code>
            <supplier_code>B515C16CRU</supplier_code>
            <images>
                <img_item type_name="">https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3378-72-B.jpg</img_item>
                <img_item type_name="">https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3379-72-B.jpg</img_item>
                <img_item type_name="">https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3380-72-B.jpg</img_item>
            </images>
        </product>
    </products>'''
    
    root = ET.fromstring(string)
    
    headers = ('code', 'ws_code', 'supplier_code', 'images')
    
    with open('test.csv', 'w', newline='') as f:
        writer = csv.DictWriter(f, fieldnames=headers)
        writer.writeheader()
        for product in root.iter('product'):
            writer.writerow({'code': product.find('code').text,
                             'ws_code': product.find('ws_code').text,
                             'supplier_code': product.find('supplier_code').text,
                             'images': ';'.join(img.text for img in product.iter('img_item'))})
    

    生成以下 CSV:

    code,ws_code,supplier_code,images
    722,B515C16CRU,B515C16CRU,https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3378-72-B.jpg;https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3379-72-B.jpg;https://www.apparel.com.tr/stance-corap-cruker-grey-orap-stance-ankle-bters-3380-72-B.jpg
    

    【讨论】:

    • 我的控制台出现xml.etree.ElementTree.ParseError: not well-formed (invalid token): line 28, column 2 错误。
    • @Omercan 这意味着您尝试使用的 XML 文件是 not well-formed
    • 我确定它的格式很好。因为 xml2csv 正在给出输出。
    • @Omercan 将您尝试解析的 actual 文件以正确格式添加到您的问题中。
    【解决方案2】:
    import xml.etree.ElementTree as ET
    import csv
    import re
    
    class xml_to_csv:
    def do(self):
       #self.xml_file_location = input("Enter full path of XML file(Eg =                   D:\programs\ResidentData.xml) : ")
       self.tree = ET.parse("urunler-fotolu.xml")
       self.root = self.tree.getroot()
       self.csv_file_location = input("Enter full path to store CSV file(Eg = D:\programs\csv_file.csv ) : ")
       self.csv_data = open(self.csv_file_location, 'w')
       self.csv_writer = csv.writer(self.csv_data)
       self.find_records(self.root)
    
    def find_attributes(self,record):
       temp = []
       dont_do = 0
       for j in record:
           temp = temp + self.find_attributes(j)
           dont_do = 1
       if(dont_do == 0):
           return [record.text]
       return temp
    
    def find_records(self,root1):
        for i in root1:
            csv_record = self.find_attributes(i)
    
            sz = len(csv_record)
            i=0
            while (i<sz):
                if csv_record[i][0] == '\n':
                     csv_record[i] = csv_record[i][1:len(csv_record[i])-1]
                i = i+1;
            print(csv_record)
            self.csv_writer.writerow(csv_record)
    
    
    if __name__ == "__main__":
        obj = xml_to_csv()
        obj.do()
    

    输入:

    For this = """
         <State>
           <Resident Id="100">
              <Name>Sample Name</Name>
              <PhoneNumber>1234567891</PhoneNumber>
              <EmailAddress>sample_name@example.com</EmailAddress
              <Address>
                            <StreetLine1>Street Line1</StreetLine1>
                            <City>City Name</City>
                            <StateCode>AE</StateCode>
                            <PostalCode>12345</PostalCode>
              </Address>
         </Resident>
         </State>
    """
    

    输出:

      ['Sample Name', '1234567891', 'sample_name@example.com', 'Street Line1', 'City Name', 'AE', '12345']
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-18
    • 2014-01-18
    • 1970-01-01
    • 2021-11-28
    • 2015-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多