powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Исправление кодировки XML
6 сообщений из 6, страница 1 из 1
Исправление кодировки XML
    #34933580
petropavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте!

Имеется программа (Delphi7, чужая, без исходников), хранит свои данные в XML (некоторая около-бухгалтерская "набивалка" данных в таблички).
(Вероятно, здесь это неважно, но это именно борландовский вариант XML под названием DATAPACKET, что очень похоже на DBF по сути - есть описание колонок таблицы, есть набор строк).

Проблема начинается с того, что библиотеке, которая работает с этим XML, очевидно, забыли объяснить, что данные ей даются на русском языке. Поэтому библиотека считает, что ей дали на вход западноевропейские буквы (латиница+латиница с умляутами), и, как положено, конвертирует их в Юникод, как умеет, и сохраняет.

В результате получаем внутри XML элементы такого вида: <goal> & #206;& #239;& #235;& #224;& #242;& #224;</goal> ( Ну, без пробелов между & и #, изначально это было слово "оплата").

Хочется производить некоторые манипуляции с этими данными помимо "родной", их создавшей, программы. Однако, чем бы я ни открывал этот файл, получаем что-то вроде <goal>Îïëàòà</goal>
(тут буквы с крышечками и чёрточками).

Почесамши затылок, родилось нечто на Python-е:

import xml.dom.minidom
dom=xml.dom.minidom.parse("имяфайла.xml")
sstr = dom.toxml("cp1252")
sstr = sstr.replace("<?xml version=\"1.0\" encoding=\"cp1252\"?>", "<?xml version=\"1.0\" encoding=\"windows-1251\"?>", 1)
sstr = sstr.replace("<ROW>", "\n<ROW>")
print sstr

(суть - преобразовываю XML в строчку на "западноевропейском" языке, затем обманом выставляю в заголовке ему, что это русский 1251)

Оно, на удивление. даже работает, и даёт на выходе русские буковки.
Однако, в реальной ситуации за год доблестные бухи наколотили 12 мегабайт этих "оплат", и Питон на этом скрипте (предсказуемо, впрочем) потребляет 350 Мбайт памяти (сначала весь файл преобразуется в большой DOM в памяти, потом в большую строку. Оно работает, но несколько некошерно. Есть такое ощущение, что проблема имеет какие-то более правильные пути решения, но в книжках такое вряд ли вычитаешь, а я в XML делаю первые робкие шаги.

Я, конечно, читал про SAX, по ощущениям это то, что нужно, (сделать фильтр, который будет каждый поступивший ему на вход элемент сразу конвертировать как надо и выводить), но сам я это не осиливаю.
Возможно, тут подошёл бы какой-то трюк с XML Transformation.

Прямой вариант - заставить автора пофиксить программу, по ряду причин недоступен.

Тупая замена кодировке в заголовке файла на ...encoding="windows-1251... толку не даёт, так как html-entity & #206 это строго "большая I с крышечкой", независимо от енкодинга в заголовке.


В общем, уважаемые камрады, дайте направляющего пинка, пожалуйста. Что почитать, по каким словам ключевым гуглить.

Заранее премного благодарен!
С уважением, Владимир
...
Рейтинг: 0 / 0
Исправление кодировки XML
    #34934105
belugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
проблема в том, что он сохраняет коды 1251, но при этом по стандарту это должен быть unicode

я бы сделал это без разбора xml а на регулярных выражениях типа
Код: plaintext
1.
2.
3.
4.
import re
pattern = re.compile('(d+);')
str = file("имяфайла.xml").read()
file('out.xml').write(pattern.sub(lambda x: chr(int(x.group( 1 ))), str))

еще можно построчно обработать...
...
Рейтинг: 0 / 0
Исправление кодировки XML
    #34935094
petropavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Самую малость поправил, заработало вот в таком варианте:

Код: plaintext
1.
2.
3.
4.
import re
pattern = re.compile('([0-9]+);')
str = file("имяфайла.xml").read()
file('out.xml','w').write(pattern.sub(lambda x: chr(int(x.group( 1 ))), str))

На 12-мег файле работает 3 секунды, отъедает памяти около 30 мегабайт.

Огромное спасибо за конкретный пример по существу!

честно говоря, в Питоне я примерно такой же чайник, как и в XML, сам бы такую конструкцию вряд ли соорудил.

Однако, вопрос такой: то, что в данном случае оказалось удобным обрабатывать XML, как текст - это именно случай такой "не-хрестоматийный" ? или это на самом деле частое явление? А то я тут комплексую по поводу того, что, добавив в XML переводы строк, потом фильтрую его grep-ом и заменяю в нём значения элементов при помощи AWK, может, зря комплексую?
...
Рейтинг: 0 / 0
Исправление кодировки XML
    #34935254
belugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petropavel
Однако, вопрос такой: то, что в данном случае оказалось удобным обрабатывать XML, как текст - это именно случай такой "не-хрестоматийный" ? или это на самом деле частое явление? А то я тут комплексую по поводу того, что, добавив в XML переводы строк, потом фильтрую его grep-ом и заменяю в нём значения элементов при помощи AWK, может, зря комплексую?

В разрезе этой проблемы xmlность этого файла была несущественна.

Плюс зачем-то нужна была экономия памяти.

Если бы пришлось как-то анализировать его структуру я бы предпочел использовать elementtree или SAX.
...
Рейтинг: 0 / 0
Исправление кодировки XML
    #34935543
petropavel
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
В том варианте, что я озвучил - да, XMLность несущественна, 100% согласен.

Однако если дальше развить пример с данной конкретной программой - у неё есть еще другой набор XML-файлов того же толка, правда, они не изменяются, как вышеописанные, ибо это справочники (плюс это справочники по размеру маленькие). Внутри них содержится таким же образом покорёженный юникод, но не в виде ...; а в двухбайтовом представлении (тоже при открытии Exlporer-ом и Excel-ом дают акцентированные символы.

Фокус с импортом в DOM -> строку -> кодировку на них в принципе работает, таким образом, получается, что рассмотрение файлов, как XML-ных, при своём неудобстве, даёт бОльшую универсальность.

Я для таких файлов с грехом пополам нарисовал конвертор, тоже на Python, он ходит по дереву DOM путём вызовов getElementsByTagName, childNodes.

Но судя по уродливости получившихся у меня конструкций (при довольно простом устройстве исходного XML-а), мне надо изучать хорошие примеры работы с XML из Python.

Исправление же кодировки (когда уже добрался до массива "кривых" текстовых значений элементов у меня получилось такое:

Код: plaintext
1.
2.
3.
import codecs
...
map ( lambda x: x.encode('cp1252','replace'), text_strings )

(без 'replace' данный код иногда падает с диагностикой примерно переводимой как "встретился несуществующий в кодировке символ").

UPD. Премного благодарен за реальную помощь ! Пошёл читать про elementtree !
...
Рейтинг: 0 / 0
Исправление кодировки XML
    #34935773
belugin
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
вообще с питоноспецифичными вещями лучше в Zopyrus
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / XML, XSL, XPath, XQuery [игнор отключен] [закрыт для гостей] / Исправление кодировки XML
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]