| Название: [решено] Чтение XML, запись XML Отправлено: sergek от Января 06, 2010, 17:10 Коллеги!  Подскажите, пожалуйста, правильно ли я понял - при чтении и обработке содержимого xml-файлов большого размера (сотни кбайт - десятки Мбайт) средствами Qt следует использовать QXmlSimpleReader, для записи результатов в xml-файл - QXmlStreamWriter? DOM прошу не предлагать, не подходит. С SAX понятно - для чтения, а вот примеров создания xml-файлов нашел немного. Особенно порадовал SAX Bookmarks Example :( Спасибо. Название: Re: Чтение XML, запись XML Отправлено: Akaiten от Января 15, 2010, 15:46 Для чтения использую QXmlStreamReader, для создания QXmlStreamWriter. А что с созданием непонятно? это ж проще пареной репы. Например Код 
 Должно получиться что то вроде этого Код 
 Добавлено 18.01.2010 11:14: Забыл закрывающий тег для <img> :) Название: Re: Чтение XML, запись XML Отправлено: Marat(Qt) от Января 16, 2010, 16:29 Должно получиться что то вроде этогоТэг img не закрыт Код 
 Название: Re: Чтение XML, запись XML Отправлено: Resager от Января 16, 2010, 22:02 Тэг img не нуждается в закрытии, однако по стандарту XHTML 1.0 нужно дописывать (для такого типа тэгов) в конце "/" Как то: <img src="image.jpg" alt="image" /> (читать здесь http://stepbystep.htmlbook.ru/?id=63) Неужели там это непридусмотрено? :( Мне как раз понадобится работа с XML файлами... не подскажете ли (пару примерчиков) чтения XML-файла? Меня особенно интересует, можно ли "добавлять" в XML, в середину, текст большей размерности (буду использовать по прототипу БД, для хранения многострочных текстовых данных), не использую нормальные БД по причине того. что поле ограниченной длины. Например было: Код 
 Стало: Код ( Ну и конечно чтобы это быстро было. Название: Re: Чтение XML, запись XML Отправлено: Marat(Qt) от Января 16, 2010, 23:09 Если положите это в value=... (т.е. в атрибут), то наткнетесь на ту же проблему что и в соседнем топике http://www.prog.org.ru/topic_11648_0.html (http://www.prog.org.ru/topic_11648_0.html) Если будете активно DOM использовать - то вся база будет в ОЗУ лежать, а так вполне ничего. Жить можно будет. Название: Re: Чтение XML, запись XML Отправлено: Resager от Января 17, 2010, 13:02 Есть хорошие примеры для работы с DOM? Это хорошо, с одной стороны, что хранится будет в ОЗУ, и быстро, и как вы говорите проблем меньше, а если мне не охота нагружать ОЗУ этив файлом, ибо предпологается большой размер файла (~100 мб максимум). Думаю надо проверить на быстродействие оба варианта, и если видимого отличия не будет, тогда лучше не занимать память. Класть мне всё равно куда, хотя в "KEY", хоть вообще между тэгами (ибо придётся как уже говорил как то многострочные текстовые блоки хранить). Так сможете подсказать? З.Ы. В примере выше не показано, как например подключать файл, если не сложно. покажите?! Название: Re: Чтение XML, запись XML Отправлено: sergek от Января 17, 2010, 14:30 Для чтения использую QXmlStreamReader, для создания QXmlStreamWriter. А что с созданием непонятно? это ж проще пареной репы. НапримерЯ бы не назвал это пареной репой :) Однако ход мысли понятен, спасибо. Предстоит много нудной и противной работы  :( Код 
 Название: Re: Чтение XML, запись XML Отправлено: Marat(Qt) от Января 17, 2010, 15:11 Есть хорошие примеры для работы с DOM? Это хорошо, с одной стороны, что хранится будет в ОЗУ, и быстро, и как вы говорите проблем меньше, а если мне не охота нагружать ОЗУ этив файлом, ибо предпологается большой размер файла (~100 мб максимум). Думаю надо проверить на быстродействие оба варианта, и если видимого отличия не будет, тогда лучше не занимать память.У xml есть язык запросов - XQuery, не знаю как он для вставки (по сути должны быть средства) но вот для чтения очень даже. Составляете запрос и получаете конкретную строку или набор строк, удовлетворяющих запросу. Класть мне всё равно куда, хотя в "KEY", хоть вообще между тэгами (ибо придётся как уже говорил как то многострочные текстовые блоки хранить). Так сможете подсказать? Название: Re: Чтение XML, запись XML Отправлено: Akaiten от Января 18, 2010, 11:19 Меня особенно интересует, можно ли "добавлять" в XML, в середину, текст большей размерности ... Ну и конечно чтобы это быстро было. Обычно, чтобы изменить XML файлик требуеться его полностью прочитать (и обычно распарсить) в память. Название: Re: Чтение XML, запись XML Отправлено: Resager от Января 18, 2010, 16:29 Обычно, чтобы изменить XML файлик требуеться его полностью прочитать (и обычно распарсить) в память.Ну это логично, по другому думаю никак, даже текстовый файл... Как происходит загрузка в память XML-файла и его парсинг, что для этого есть в QT? Название: Re: Чтение XML, запись XML Отправлено: Marat(Qt) от Января 18, 2010, 16:50 Обычно, чтобы изменить XML файлик требуеться его полностью прочитать (и обычно распарсить) в память.Ну это логично, по другому думаю никак, даже текстовый файл... Как происходит загрузка в память XML-файла и его парсинг, что для этого есть в QT? Название: Re: Чтение XML, запись XML Отправлено: Akaiten от Января 18, 2010, 17:03 Обычно, чтобы изменить XML файлик требуеться его полностью прочитать (и обычно распарсить) в память.Ну это логично, по другому думаю никак, даже текстовый файл... Как происходит загрузка в память XML-файла и его парсинг, что для этого есть в QT? Могу ещё раз написать, что я, например, использую QXmlStreamReader. Если структура XML довольна проста, то при помощи QXmlStreamReader его можно просто и быстро распарсить. В качестве примера смотри Qt\tools\linguist\shared\ts.cpp - парсер TS-файлов. Также для чтения можно использовать QXmlSimpleReader (ни разу не использовал) или QDomDocument. Название: Re: Чтение XML, запись XML Отправлено: SABROG от Января 21, 2010, 10:12 QXmlStreamReader это StAX, по сути может работать с любым объемом, на его основе можно построить сетевой протокол на базе xml запросов и ответов. Т.е. ему всё равно какого размера файл, он будет работать. Из недостатков - только для чтения, только forward cursor, т.е. нельзя вернуться в предыдущую ноду и посмотреть чего там было, код парсера получается некрасивым, не понятным, много оверхеда (повторяющегося кода). Зато хорошо работает. Название: con: Чтение XML, запись XML Отправлено: sergek от Января 28, 2010, 22:07 Коллеги, в продолжение темы. При записи с помощью QXmlStreamWriter xml-документа нужно, чтобы в декларацию xml записывалась кодировка, типа <?xml version="1.0" encoding="WINDOWS-1251"?>. Курю assistant, в котором говорится что при использовании QXmlStreamWriter::setCodec ( QTextCodec * codec ) the encoding information is stored in the initial xml tag. Главное, чтобы вызов this function был before calling writeStartDocument(). Пишу QXmlStreamWriter writer; writer.setCodec("WINDOWS-1251"); writer.writeStartDocument(); Фигвам. В созданном документе декларация выглядит как <?xml version="1.0"?> без encoding. Думал, что кодек кривой, так нет - если сделать QTextCodec * c=writer.codec(); QString sc=c->name(); то sc показывает правильно: windows-1251. Пробовал разную кодировку, в том числе UTF, все едино... Подскажите, как правильно сформировать декларацию в прологе? Гуру, ау!!! Название: Re: Чтение XML, запись XML Отправлено: BRE от Января 28, 2010, 22:28 Попробуй воспользоваться этим: void QXmlStreamWriter::writeProcessingInstruction ( const QString & target, const QString & data = QString() ) Название: Re: Чтение XML, запись XML Отправлено: Akaiten от Января 29, 2010, 09:46 Encoding записывается только в случае, если QXmlStreamWriter пишет в QIODevice. Название: Re: Чтение XML, запись XML Отправлено: SABROG от Января 29, 2010, 14:11 Создаю xml через QXmlStreamWriter, в качестве устройства передаю QByteArray (он не QIODevice). Без явной установки кодировки получаю "UTF-8", при Windows-1251: Код 
 Получаю в xml - "Windows-1251". Qt 4.6.1. Всё работает. Название: Re: Чтение XML, запись XML Отправлено: sergek от Января 29, 2010, 20:51 Цитировать Encoding записывается только в случае, если QXmlStreamWriter пишет в QIODevice Цитировать Создаю xml через QXmlStreamWriter, в качестве устройства передаю QByteArray (он не QIODevice)Вот где собака порылась! Из трех конструкторов QXmlStreamWriter с параметрами QIODevice, QByteArray и QString я выбрал тот, который мне был понятнее (последний). А он-то и работает кривовато. Просто заменил строку Код: QString outXml; на Код: QByteArray outXml; и что хотел, получил. Спасибо! Название: Re: Чтение XML, запись XML Отправлено: warlock от Февраля 08, 2010, 00:42 Возможно ли обновлять xml файл без полной его перезаписи? Т.е. обновить какуето запись? Название: Re: Чтение XML, запись XML Отправлено: sergek от Февраля 25, 2010, 21:21   Коллеги, еще вопрос, если позволите.  Нет ли какой-нибудь особенности преобразования прописной русской буквы "И" из UTF-8 с помощью QTextCodec? Проблема следующая. Имеется файл примерно такой (скопировано из QTextEdit): Код: <?xml version="1.0" encoding="UTF-8"?> Я его загружаю с помощью QTextStream с отключенным автоопределением кодировки, затем перекодирую в Unicode с использованием кодека QTextCodec::codecForName("UTF-8"). Получаю Код: <?xml version="1.0" encoding="UTF-8"?> Если читать этот же файл с использованием QXmlSimpleReader, то значение атрибута передается правильно: Код: Acc="11111ИИ1111111111111" Кодеки ForTr, ForLocale, ForCStrings установлены в "windows-1251". Такое ощущение, что я что-то не понимаю (и не только я - топики с кодировками тут обширные, я их полистал). На всякий случай, некоторые куски кода: Код:     QTextCodec *cp1251 = QTextCodec::codecForName("windows-1251");Название: Re: Чтение XML, запись XML Отправлено: SABROG от Февраля 26, 2010, 03:05 Код 
 Что вижу я из этого кода. Ставим локаль в cp1251, открываем поток, который берет текущий кодек локали (cp1251) и отключаем определение кодировок UTF-16 и UTF-32 через BOM (который не добавляют большинство текстовых редакторов). В строчке с stream.readAll() в text текст попадает уже в юникоде. cp1251->Unicode 4.0 Затем мы берем строку text (которая у нас уже в Unicode 4.0) и добавляем в QByteArray. Выбираем кодек UTF-8 и ...: выполняем преобразование Unicode 4.0 в Unicode 4.0, обманывая кодек, сказав ему, что у нас там UTF-8. Но UTF8/16/32 и т.д != Unicode. UTF - представление кодировки, где тот же английский текст записывается как один байт на символ, в то время как в Unicode отводится 2 байта на любой символ. В какой бы ты кодировке не грузил файл через QTextStream содержимое будет всегда конвертироваться как cp1251->Unicode, так как ты сам выбрал кодировку для локали. И не важно в какой кодировке сам файл, QTextStream не умеет определять кодировки налету. Поэтому либо вызывай QTextStream::setCodec(), которому подставляй кодировку в которой у тебя файл, либо в конструктор подставляй QString, предварительно считав содержимое из файла (QFile) и преобразовав кодировку вручную. Название: Re: Чтение XML, запись XML Отправлено: sergek от Февраля 26, 2010, 20:15 Цитировать В строчке с stream.readAll() в text текст попадает уже в юникоде. cp1251->Unicode 4.0Верно. Цитировать Затем мы берем строку text (которая у нас уже в Unicode 4.0) и добавляем в QByteArray. Выбираем кодек UTF-8 и ...: выполняем преобразование Unicode 4.0 в Unicode 4.0, обманывая кодек, сказав ему, что у нас там UTF-8А это не так. Вы пропустили пару строк из моего поста: Код: QByteArray xml; Для всех других русских букв, кроме "И" это выполняется, попробуйте. Цитировать QTextStream не умеет определять кодировки налетуЕсли есть BOM, то умеет. В общем, пока причина непонятна. Но то, что мне нужно, я получил - просто выкинул QTextStream за ненадобностью: Цитировать QFile file(fileName);Таким образом, взаимная перекодировка устранена, глюков нет. file.open(QFile::ReadOnly | QFile::Text); QByteArray xml=file.readAll(); Спасибо за подсказки. Название: Re: Чтение XML, запись XML Отправлено: SABROG от Февраля 27, 2010, 00:52 В общем, пока причина непонятна. Возможно происходит что-то о чем сказано здесь: Цитировать Warning: Some codecs do not preserve the characters in the ASCII range (0x00 to 0x7F). For example, the Japanese Shift-JIS encoding maps the backslash character (0x5A) to the Yen character. To avoid undesirable side-effects, we recommend avoiding such codecs with setCodecsForCString(). Для проверки верни QTextStream и просто вызови QByteArray::append(). А потом сохрани его содержимое в файл. Я никогда не использовал глобальную установку кодеков вручную и делать этого никогда не буду и никому не советую. Название: Re: Чтение XML, запись XML Отправлено: sergek от Марта 01, 2010, 10:34 Цитировать У меня все кодеки одинаковые, поэтому должно выполняться обратное преобразование Unicode->cp1251, и в xml текст должен быть в честном UTF-8Причина, более-менее, понятна - в неэквивалентности прямых и обратных преобразований. Наверное, можно выстроить эти цепочки, но я сделал по-другому. XML-файл загружаю в QByteArray, сохраняя кодировку. Затем определяю кодировку этого файла, используя QXmlSimpleReader преобразую исходный текст честным кодеком (соответствующим кодировке) в unicode - для его просмотра и редактирования. Когда нужен исходный текст, выполняю обратное преобразование из unicode в первоначальную кодировку. В общем, решение очевидное. Цитировать Я никогда не использовал глобальную установку кодеков вручную и делать этого никогда не буду и никому не советуюПрокомментируйте, пожалуйста. Например, чем плох вариант: Код: QTextCodec * codec = QTextCodec::codecForLocale(); Название: Re: Чтение XML, запись XML Отправлено: SABROG от Марта 01, 2010, 13:47 Слово "вручную" означало в данном контексте "жестко заданную". В то время как codecForLocale() автоматическая, это я использую в своих приложениях и то для нормального вывода отладочной информации в консоль. А вот это явно лишнее. Кодировка исходников может не совпадать с кодировкой локали. Код: QTextCodec::setCodecForTr(codec); Название: Re: Чтение XML, запись XML Отправлено: sergek от Марта 01, 2010, 14:10 Еще вопрос. Для определения кодировки исходного xml-файла в обработчике QXmlSimplReader я делаю Код: class CUfebsHandler : public QXmlDefaultHandler Название: Re: Чтение XML, запись XML Отправлено: SABROG от Марта 01, 2010, 14:28 Остается ощущение, что это велосипед. Нет ли стандартных средств? Есть. Все классы использующие QXmlInputSource автоматически определяют кодировку, если они не могут её определить, то используется UTF-8 или UTF-16. Название: Re: Чтение XML, запись XML Отправлено: sergek от Марта 02, 2010, 10:24 Цитировать Все классы использующие QXmlInputSource автоматически определяют кодировкуЯ в этом и не сомневался :) А выдают ли они ее наружу? Как в обработчиках получить значение encoding из декларации? Название: Re: Чтение XML, запись XML Отправлено: SABROG от Марта 02, 2010, 12:38 Не выдают. Кодек хранится в указателе d_ptr (QXmlSimpleReaderPrivate)  private секции класса QXmlSimpleReader. Достучаться можно унаследовав QXmlSimpleReader через using. Название: Re: Чтение XML, запись XML Отправлено: sergek от Марта 12, 2010, 22:59 Коллеги! Проект (библиотека для работы с xml-документами определенного формата), в связи с которым я и начал этот топик, почти завершен. Если есть желание, можно ознакомиться с ним по ссылке: http://get.freesoft.ru/?id=106788 (http://get.freesoft.ru/?id=106788) Архив включает скомпилированный демонстрационный пример для Windows. Если влом тянуть весь проект (4.6 Мб), можно ознакомиться с документацией на него (руководство программиста): http://get.freesoft.ru/?id=106789 (http://get.freesoft.ru/?id=106789) Надеюсь, что вы найдете там кое-что полезное, тем более, что я попытался выработать некоторый общий подход к решению подобных задач. Если кто-то не сочтет за труд это прочитать и высказать свои суждения, буду весьма признателен. Со своей стороны прошу all поделиться функцией формирования суммы прописью, которую можно было бы включить в библиотеку. Собственно, у меня есть такая, но я не знаю автора, и неудобно включать ее во фриварный софт. Название: Re: Чтение XML, запись XML Отправлено: sergek от Марта 21, 2010, 15:36 Выпущена новая версия библиотеки (ссылки выше исправлены). Если кому интересно, обновления смотрите на сайте, указанном в документации (после модерации программы).  Тему завершаю, всем спасибо. Название: Re: [решено] Чтение XML, запись XML Отправлено: voronElf от Марта 22, 2010, 09:09 Насчет формирования суммы прописью, отдаю свою как есть. Только писал давно, зеленый был, ногами сильно не бить ))) Код: QString CModDocs::priceToText(double price) |