Найти - Пользователи
Полная версия: Парсинг xml файла в ISO-8859-1
Начало » Python для новичков » Парсинг xml файла в ISO-8859-1
1
Pulivech
Здравствуйте. Есть 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; 
...
Подскажите, как правильно работать с таким файлом.
Pulivech
Если попробовать открывать через модули, вроде xml.etree или xmltodict с указанием encoding='ISO-8859-1', то всегда получаю:
xml.parsers.expat.ExpatError: not well-formed (invalid token): line 1, column 40
py.user.next
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'}
>>>
Pulivech
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.
Pulivech
py.user.next
Да ты не понимаешь, где какая кодировка. Есть кодировка документа XML, есть кодировка файла XML, есть кодировка исходника на питоне. И это всё разные кодировки.
Возможно. В чем разница между ними? Если я открываю xml файл с определенной кодировкой и при этом указываю encoding='ISO-8859-1', это не значит, что я все правильно сделал?

По поводу вашего примера, да, с 1 строчкой у меня тоже все ок. Но если парсить весь файл, получаются те ошибки, которые я выше привел. Вот пример файла, кстати.
py.user.next
Там кодировка у документа 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]$
Pulivech
py.user.next
вы попробуйте получить информацию из 2 тега или как он называется в разметке по всем строкам после 2-ой. У вас будет кракозябра, потому что кодировка ISO-8859-1, а не utf-8. Я имею ввиду сам текст внутри тегов, которые получается через .text.
py.user.next
Тот файл, который ты передал, не содержит текста в тегах.
Только в атрибутах (в именах и значениях) есть кириллица и всё читается прекрасно.

  
#!/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-файл, скорее всего.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB