Редактирование XML файла c помощью regex

superuser007

Новичок
Пользователь
Апр 8, 2020
5
1
3
Здравствуйте, прошу помощи у знающих людей, поставщик присылает прайс в xml файле, в нем есть строки

XML:
<categories>
<category id="[B]137[/B]" parentId="136">[B]Батарейки[/B]</category>
<category id="139" parentId="141">Аккумуляторы</category>
<category id="140" parentId="162">Пружины</category>
<category id="2701" parentId="43432">Элементы питания</category>
<category id="[B]24227[/B]" parentId="2701">[B]Зарядные устройства[/B]</category>
</categories>
<products>
<product id="11223344" available="true">
<price>22.00</price>
[B]<categoryId>24277</categoryId>[/B]
<delivery>true</delivery>
<name>Фонарик-ручка «Универсал», 1 диод, микс</name>
<description>Перед вами компактная функциональная модель фонарика с ручкой</description>
<param name="Состав">Пластик</param>
</product>
<product id="55667788" available="true">
<price>22.00</price>
[B]<categoryId>137</categoryId>[/B]
<delivery>true</delivery>
<name>Батарейка солевая</name>
<description>Пальчиковая батарейка, солевая</description>
<param name="Тип">АА</param>
</product>
</products>

в python новичок, пытался с помощью регулярного выражения вырезать 137 из <category id="137" parentId="136">Батарейки</category> сопоставить его с карточкой товара в которой <categoryId>137</categoryId> и если значение совпадает подставить название категории в нашем случае это Батарейки что бы получилось не <categoryId>137</categoryId> а <categoryId>Батарейки</categoryId>. Может кто помочь в данной проблеме? заранее благодарен
 

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
Вот простой пример на срезах:
Python:
d = {}
category_id = None
category_name = None
with open('1.xml', 'r', encoding='utf-8') as f:
    next(f)
    for i in f:
        if '</categories>' in i:
            break
        else:
            category_id = i.split('"')[1]
            i1 = i.split('>')[1].index('<')
            category_name = i.split('>')[1][:i1]
            d[category_id] = category_name

with open('1.xml', 'r', encoding='utf-8') as f, open('2.xml', 'w', encoding='utf-8') as f2:
    for s in f:
        if '<categoryId>' in s:
            x = ''
            i1 = s.index('<categoryId>')
            i2 = s.index('</')
            x = s[i1 + 12:i2]
            try:
                s = s.replace(x, d[x])
            except:
                pass
            
        f2.write(s)
Вместо 1.xml поставьте свой файл, вместо 2.xml - имя файла с результатом. Скрипт поменяет все совпадающие categoryID на названия.
 
  • Мне нравится
Реакции: superuser007

stud_55

Модератор
Команда форума
Модератор
Апр 3, 2020
1 522
672
113
что то пошло не так, выдает такую ошибку

Python:
i1 = i.split('>')[1].index('<')
ValueError: substring not found
Вот второй вариант - с проверками:
Python:
d = {}
category_id = None
category_name = None
with open('1.xml', 'r', encoding='utf-8') as f, open('2.xml', 'w', encoding='utf-8') as f2:
    for s in f:
        if '</category>' in s:
            try:
                category_id = s.split('"')[1]
                i1 = s.split('>')[1].index('<')
                category_name = s.split('>')[1][:i1]
                d[category_id] = category_name
            except:
                pass

        if '<categoryId>' in s:
            try:
                i1 = s.index('<categoryId>')
                i2 = s.index('</')
                x = s[i1 + 12:i2]
                s = s.replace(x, d[x])
            except:
                pass
            
        f2.write(s)
Хотя конечно лучше делать с помощью BeautifulSoup.
 

superuser007

Новичок
Пользователь
Апр 8, 2020
5
1
3
что то пошло не так, выдает такую ошибку

Python:
i1 = i.split('>')[1].index('<')
ValueError: substring not found
 

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
XML и HTML нельзя парсить регулярными выражениями. Технически это возможно, но лучше не стоит. Воспользуйся библиотекой BeautifulSoup.
Вот статья у нас на портале: https://python-scripts.com/beautifulsoup-html-parsing
И вот еще: https://pythonprogramming.net/tables-xml-scraping-parsing-beautiful-soup-tutorial/
 
  • Мне нравится
Реакции: superuser007

superuser007

Новичок
Пользователь
Апр 8, 2020
5
1
3
XML и HTML нельзя парсить регулярными выражениями. Технически это возможно, но лучше не стоит. Воспользуйся библиотекой BeautifulSoup.
Вот статья у нас на портале: https://python-scripts.com/beautifulsoup-html-parsing
И вот еще: https://pythonprogramming.net/tables-xml-scraping-parsing-beautiful-soup-tutorial/
Cпасибо, буду разбираться, правда всё очень тяжко дается. Всё равно огромное Вам спасибо, а то рутинная работа уже доканывает
 
  • Мне нравится
Реакции: Student

Student

throw exception
Команда форума
Администратор
Апр 2, 2020
195
103
43
Москва
@superuser007 все получится. Если что мы тут на форуме!
 
  • Мне нравится
Реакции: superuser007

superuser007

Новичок
Пользователь
Апр 8, 2020
5
1
3
Насколько я понимаю теперь данный код который представлен выше, не подойдет, даже если загружать библиотеку bs4 , всё верно?
 

superuser007

Новичок
Пользователь
Апр 8, 2020
5
1
3
Вот второй вариант - с проверками:
Python:
d = {}
category_id = None
category_name = None
with open('1.xml', 'r', encoding='utf-8') as f, open('2.xml', 'w', encoding='utf-8') as f2:
    for s in f:
        if '</category>' in s:
            try:
                category_id = s.split('"')[1]
                i1 = s.split('>')[1].index('<')
                category_name = s.split('>')[1][:i1]
                d[category_id] = category_name
            except:
                pass

        if '<categoryId>' in s:
            try:
                i1 = s.index('<categoryId>')
                i2 = s.index('</')
                x = s[i1 + 12:i2]
                s = s.replace(x, d[x])
            except:
                pass
           
        f2.write(s)
Хотя конечно лучше делать с помощью BeautifulSoup.

Спасибо, всё работает. с BeautifulSoup я так и не разобрался ;(
 

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