Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 4, 2018 12:37:04

Pulivech
Зарегистрирован: 2018-08-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

Здравствуйте. Есть xml файл, который правильно отображается только через edge/explorer. Выглядит так:

<?xml version="1.0" encoding="ISO-8859-1"?>
<Файл КолДок="294" ТипИнф="ОТКРДАННЫЕ1" ВерсПрог="1.0" ВерсФорм="4.01" ИдФайл="VO_OTKRDAN1_9965_9965_20180731_000a528a-e339-4def-92ad-b5a9dbd18e31">
...
Хочу парсить такой файл.
Нашел информацию, что это кодировка latin-1. Пробую использовать
# -*- coding: latin-1 -*-
и
# -*- coding: ISO-8859-1 -*-
Но в итоге все равно получаю
UnicodeDecodeError: 'charmap' codec can't decode byte 0x98 in position 49: character maps to <undefined>
Если преобразовать в utf-8 через
decode('iso-8859-1').encode('utf8')
читать из файла я могу, но только в таком виде:
<?xml version="1.0" encoding="UTF-8"?><Файл ИдФайл="VO_OTKRDAN1_9965_9965_20180731_000a528a-e339-4def-92ad-b5a9dbd18e31" ВерсФорм="4.01" ВерсПрог="1.0" ТипИнф="&#x41E;&#x422;&#x41A;&#x420;&#x414;&#x410;&#x41D;&#x41D;&#x42B;&#x415;1" КолДок="294"><ИдОтпр><ФИООтв Фамилия="_" Имя="_"/></ИдОтпр><Документ ИдДок="06e5e343-a969-818f-cab7-6d0efdb54494" ДатаДок="31.07.2018" ДатаСост="01.01.2018"><СведНП НаимОрг="&#x41E;&#x411;&#x429;&#x415;&#x421;&#x422;&#x412;&#x41E; &#x421; &#x41E;&#x413;&#x420;&#x410;&#x41D;&#x418;&#x427;&#x415;&#x41D;&#x41D;&#x41E;&#x419; 
...
Подскажите, как правильно работать с таким файлом.

Офлайн

#2 Авг. 4, 2018 12:43:16

Pulivech
Зарегистрирован: 2018-08-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

Если попробовать открывать через модули, вроде xml.etree или xmltodict с указанием encoding='ISO-8859-1', то всегда получаю:

xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 40

Офлайн

#3 Авг. 4, 2018 12:59:24

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

Pulivech
Пробую использовать
Да ты не понимаешь, где какая кодировка. Есть кодировка документа XML, есть кодировка файла XML, есть кодировка исходника на питоне, есть кодировка вывода консоли. И это всё разные кодировки.

  
>>> import xml.etree.ElementTree as ET
>>> 
>>> s = '<Файл КолДок="294" ТипИнф="ОТКРДАННЫЕ1" ВерсПрог="1.0" ВерсФорм="4.01" ИдФайл="VO_OTKRDAN1_9965_9965_20180731_000a528a-e339-4def-92ad-b5a9dbd18e31" />'
>>> 
>>> doc = ET.fromstring(s)
>>> doc
<Element 'Файл' at 0x7fc3e6ffac28>
>>> doc.attrib
{'КолДок': '294', 'ТипИнф': 'ОТКРДАННЫЕ1', 'ВерсПрог': '1.0', 'ВерсФорм': '4.01', 'ИдФайл': 'VO_OTKRDAN1_9965_9965_20180731_000a528a-e339-4def-92ad-b5a9dbd18e31'}
>>>



Отредактировано py.user.next (Авг. 4, 2018 13:17:01)

Офлайн

#4 Авг. 4, 2018 13:03:49

Pulivech
Зарегистрирован: 2018-08-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

from lxml import etree

def xmlparser(xmlfile):
with open(xmlfile, encoding='ISO-8859-1') as f:
xml = f.read()
root = etree.fromstring(xml)
for appt in root.getchildren():
for elem in appt.getchildren():
if not elem.text:
text = "None"
else:
text = elem.text

print(elem.tag + " - " + text)

if __name__ == "__main__":
xmlparser(r'T:\downloads\opendata\1.xml')

Вот пример кода с использованием lxml. Получаю
ValueError: Unicode strings with encoding declaration are not supported. Please use bytes input or XML fragments without declaration.

Офлайн

#5 Авг. 4, 2018 13:06:52

Pulivech
Зарегистрирован: 2018-08-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

py.user.next
Да ты не понимаешь, где какая кодировка. Есть кодировка документа XML, есть кодировка файла XML, есть кодировка исходника на питоне. И это всё разные кодировки.
Возможно. В чем разница между ними? Если я открываю xml файл с определенной кодировкой и при этом указываю encoding='ISO-8859-1', это не значит, что я все правильно сделал?

По поводу вашего примера, да, с 1 строчкой у меня тоже все ок. Но если парсить весь файл, получаются те ошибки, которые я выше привел. Вот пример файла, кстати.

Прикреплённый файлы:
attachment 1.xml (194,0 KБ)

Офлайн

#6 Авг. 4, 2018 13:11:23

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

Там кодировка у документа utf-8 указана.

t.py

  
#!/usr/bin/env python3
 
import xml.etree.ElementTree as ET
 
with open('1.xml', encoding='utf-8') as fin:
    data = fin.read()
 
doc = ET.fromstring(data)
print(doc, doc.attrib)

[guest@localhost py]$ ./t.py 
<Element 'Файл' at 0x7f8e84d60048> {'ИдФайл': 'VO_OTKRDAN1_9965_9965_20180731_000a528a-e339-4def-92ad-b5a9dbd18e31', 'ВерсФорм': '4.01', 'ВерсПрог': '1.0', 'ТипИнф': 'ОТКРДАННЫЕ1', 'КолДок': '294'}
[guest@localhost py]$



Отредактировано py.user.next (Авг. 4, 2018 13:12:12)

Офлайн

#7 Авг. 4, 2018 13:19:27

Pulivech
Зарегистрирован: 2018-08-04
Сообщения: 5
Репутация: +  0  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

py.user.next
вы попробуйте получить информацию из 2 тега или как он называется в разметке по всем строкам после 2-ой. У вас будет кракозябра, потому что кодировка ISO-8859-1, а не utf-8. Я имею ввиду сам текст внутри тегов, которые получается через .text.

Отредактировано Pulivech (Авг. 4, 2018 13:21:53)

Офлайн

#8 Авг. 5, 2018 03:02:08

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 10003
Репутация: +  857  -
Профиль   Отправить e-mail  

Парсинг xml файла в ISO-8859-1

Тот файл, который ты передал, не содержит текста в тегах.
Только в атрибутах (в именах и значениях) есть кириллица и всё читается прекрасно.

  
#!/usr/bin/env python3
 
import xml.etree.ElementTree as ET
 
with open('1.xml', encoding='utf-8') as fin:
    data = fin.read()
 
doc = ET.fromstring(data)
for i in doc.iter():
    print(i.text, i.tail)

[guest@localhost py]$ ./t.py 
None None
None None
None None
...

Так что ты скинул не тот xml-файл, скорее всего.



Отредактировано py.user.next (Авг. 5, 2018 03:03:10)

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version