Search code examples
pythonxmlcsvlxml

lxml: create multiple tags while looping through a list in csv


I have a csv file like this:

customer, restaurant, drink, dish 
1, MC, "C1, C6", "D1, D2, D3"

and I would like to obtain a XML like that using Python lxml module:

<Example>
<Customer> 1 </Customer>
<Restaurant> MC </Restaurant>
<Drink>
   <Drink> C1 </Drink>
   <Drink> C6 </Drink>
</Drink>
<Dish> D1 </Dish>
<Dish> D2 </Dish>
<Dish> D3 </Dish>
</Example>

what I tried so far is:

import csv
import lxml.etree
from lxml import etree as ET
from lxml.builder import E

with open(r'restaurant.csv') as csvfile:
     result = E.Example(*
                         ( E.Customer(row['customer']),
                           E.Restaurant([row'restaurant']),
                           E.Drink(row['drink']),
                           E.Dish(row['dish']))

     for row in csv.DictReader(csv))
)

tree = lxml.etree.tostring(results, pretty_print=True )

with open(r'output.xml', 'wb') as f:
    f.write(tree)

I cannot figure out how to loop through this list inside of another loop.


Solution

  • You can try:

    import csv
    import lxml.etree
    from lxml import etree as ET
    from lxml.builder import E
    
    with open('data.csv', 'r') as csvfile:
        reader = csv.DictReader(csvfile)
    
        example = E.Example()
    
        for row in reader:
            example.append(E.Customer(row['customer']))
            example.append(E.Restaurant(row['restaurant']))
            drink = E.Drink()
            example.append(drink)
            for d in map(str.strip, row['drink'].split(',')):
                drink.append(E.Drink(d))
            for d in map(str.strip, row['dish'].split(',')):
                example.append(E.Dish(d))
    
    tree = lxml.etree.tostring(example, pretty_print=True)
    print(tree.decode('utf-8'))
    

    Prints:

    <Example>
      <Customer>1</Customer>
      <Restaurant>MC</Restaurant>
      <Drink>
        <Drink>C1</Drink>
        <Drink>C6</Drink>
      </Drink>
      <Dish>D1</Dish>
      <Dish>D2</Dish>
      <Dish>D3</Dish>
    </Example>
    

    contents of data.csv:

    customer,restaurant,drink,dish
    1,MC,"C1, C6","D1, D2, D3"