Парсинг XML файла в csv

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
Доброго всем дня. С python только начинаю знакомство. Поэтому сильно не пинайте. На работе поставили задачку из xml в csv перевести файлик.
В интернете нашел пример кода. Подстроил под свои задачи, ну как смог. Вроде работает. Но вложенные теги не парсит, и как до них добраться не знаю.
Подскажите. Во вложенном файле
Элемент offer основной и их много. Поля name, description, url, price, picture, vendorCode, Param - прочитываю. А вот как получить доступ к полям
Код:
<color>
  <title></title>
  <image></image>
</color>
<color>
  <title></title>
  <image></image>
</color>
<color>
  <title></title>
  <image></image>
</color>
их в каждом OFFER может быть от 1 до 10 штук.

0000001.png
Код на python вот такой. Повторюсь слино не пинайте, только учусь. Сам код нашел на просторах интренета. И под свои нужны подработал.

Python:
import xml.dom.minidom
import csv

dom = xml.dom.minidom.parse("price.xml")
dom.normalize()

csvfile = open('output.csv', 'w', encoding='utf8')
fieldnames = ['name', 'description', 'picture', 'price', 'vendorCode']
writer = csv.DictWriter(csvfile, fieldnames=fieldnames)
writer.writeheader()

i=0
#while i < len(dom.getElementsByTagName("offer")):
while i < 10:  # пока для тренировки беру первые 10 элементов
  print (" ****** ", i , " ***** ")  # для наглядности разграничиваю элементы
  nodeArray = dom.getElementsByTagName("offer")[i]
  childList=nodeArray.childNodes
  j=0
  s = [ii for ii in range(100)]
  for child in childList:
      if child.nodeType==child.TEXT_NODE:
          print(child.nodeValue)
      else:
          if child.nodeName != "categoryId" :
              s[j] = child.childNodes[0].nodeValue
              #print(child.nodeName)
              #print(child.childNodes[0].nodeValue)
              j = j +1
 
  s[6] = s[6].lower()
  if s[6].find('скл-игр') >= 0:
      writer.writerow({'name': s[0], 'description': s[1], 'picture': s[2], 'price': s[3], 'vendorCode': s[6]})
   
  i = i + 1

csvfile.close()
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 581
457
83
было бы неплохо скинуть файл xml, с одним элементом, можете изменить данные, которые заретушировали, если они особо секретные...
просто чтобы не перепечатывать с картинки...

upd
есть статья про ElementTree - https://python-scripts.com/xml-python
она вам должна помочь...
 
Последнее редактирование:

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
Что то я наверное xml файл не правильно сократил. Сейчас попровал на нем - ошибок куча. Чуть позже скину заново
 

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
Вот нормальный файл. Не корявый :)

Вот такой выводится результат с помощью "моего" кода используя этот test.xml . И вот все эти поля я заношу в csv. А вот как добраться глубже до color я не пойму :(

Python:
 ******  0  *****
name
Полка книжная ПК-30М
description
Такая закрытая настенная полка впишется в интерьер, выполненный как в классическом варианте, так и более современных стилях. Модель станет полезным дополнением в любой комнате. Размеры полки позволят разместить в ней как книги, так и игрушки, фотографии или предметы интерьера. Полка в цвете &quot;слива&quot; комплектуется задней стенкой ДВП цвета белый жемчуг. Размер: 1200Ш х 300Г х 370В
picture
/0009/4872/image_index-4872-1614777409.jpg
price
3810
currencyId
RUR
url
http://.ru/catalog/shelving/4872/
vendorCode
ПК-30М
param
370
param
300
param
1200
colors
None
schemes
None
 ******  1  *****
name
Полка книжная ПК-3
description
Простота и лаконичность.Универсальная полка. Размер: 700Ш х 250Г х 25В
picture
/0009/4882/image_full-4882-1636542953.jpg
price
990
currencyId
RUR
url
http://.ru/catalog/shelving/4882/
vendorCode
ПК-3
param
25
param
250
param
700
colors
None
optionals
None
schemes
None
>>>
 

Вложения

  • test.zip
    1,2 КБ · Просмотры: 1

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
upd
есть статья про ElementTree - https://python-scripts.com/xml-python
она вам должна помочь...
Смотрел. Я и на форум из нее попал. Но пока не разобрался. Буду конечно дальше пробовать. Но пока решил тут написать .
 

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
Ребят, я наверное почти разобрался с этой статьей. Буду дальше пытаться. Там конечно совсем другой способ, чем я тут привел....
 

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
1. Изучаю код в этой статье. Там есть такой момент:
Python:
def handleAppt(self, appt):
        begin = self.getElement(appt.getElementsByTagName("begin")[0])
        duration = self.getElement(appt.getElementsByTagName("duration")[0])
        subject = self.getElement(appt.getElementsByTagName("subject")[0])
        location = self.getElement(appt.getElementsByTagName("location")[0])
        uid = self.getElement(appt.getElementsByTagName("uid")[0])
       
        self.list.append(begin)
        self.list.append(duration)
        self.list.append(subject)
        self.list.append(location)
        self.list.append(uid)

Вот предположим что элемента UID может быть несколько и не обязательно одно и тоже, то есть может быть 2 или 5 или 1.
Если я правильно понимаю чтобы получить доступ к каждому надо писать такое примерно
uid0 = self.getElement(appt.getElementsByTagName("uid")[0])
uid1 = self.getElement(appt.getElementsByTagName("uid")[1])
uid2 = self.getElement(appt.getElementsByTagName("uid")[2])
и т.д.
Но если ("uid")[2] не существует - то выдается ошибка .... Как быть ?

2. Еще не понял что делают вот эти строчки в этой статье:
Python:
if self.flag == 'file':
            try:
                state = self.getElement(appt.getElementsByTagName("state")[0])
                self.list.append(state)
                alarm = self.getElement(appt.getElementsByTagName("alarmTime")[0])
                self.list.append(alarm)
            except Exception as e:
                print(e)
 
Последнее редактирование:

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 581
457
83
вот так можно получить вложенные теги
Python:
import xml.etree.cElementTree as ET


def parseXML(xml_file):
    tree = ET.ElementTree(file=xml_file)
    root = tree.getroot()

    for child_root in root:
        for child_root_1 in child_root:
            for child_root_2 in child_root_1:
                if child_root_2.tag == "offer":
                    for step_child in child_root_2:
                        if step_child.tag == "colors":
                            for step_child_1 in step_child:
                                for step_child_2 in step_child_1:
                                    print(step_child_2.tag, step_child_2.text)
                        if step_child.tag == "optionals":
                            for step_child_1 in step_child:
                                print(step_child_1.tag, step_child_1.text)
                        if step_child.tag == "schemes":
                            for step_child_1 in step_child:
                                print(step_child_1.tag, step_child_1.text)
                        print(step_child.tag, step_child.text)


if __name__ == "__main__":
    parseXML("test.xml")


PS
статья немного устарела, методы getchildren и getiterator убраны из новой версии питона - https://bugs.python.org/issue29209
 
  • Мне нравится
Реакции: Pavv2000

Pavv2000

Новичок
Пользователь
Янв 6, 2022
7
0
1
Спасибо большое.
 

Форум IT Специалистов