XML C8 - не понял...
Модератор: Дед Пахом
Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
- Игорь Столяров
- Ветеран движения
- Сообщения: 8082
- Зарегистрирован: 07 Июль 2005, 10:19
- Откуда: г. Ростов-на-ДоМу
- Благодарил (а): 29 раз
- Поблагодарили: 98 раз
XML C8 - не понял...
Это понятно. После раскодирования вместо русского текста в C63 какой-то мусор.
Я ведь написал, тот же самый код собранный в C91 - прекрасно загружает русский текст.

Здесь правда, надо добавить что речь идет о загрузке XML в очередь методом FromXMLFile() с последующим распарсиванием.
Make Clarion Great Again ! 
XML C8 - не понял...
Дык, у меня куча приложений с XML. По крайней мере, в CW6 парсер при декодировании UTF-8 выдаёт и значения в UTF-8
А дальше - обращение к классу CSTR для перекодировки из UTF-8 в Windows-1251
Кстати, тот же класс поможет и создать XML
А дальше - обращение к классу CSTR для перекодировки из UTF-8 в Windows-1251
Кстати, тот же класс поможет и создать XML
Код: Выделить всё
SaveManifest ROUTINE ! Сохранить манифест
DATA
CS CSTR
CODE
CS.Set('<<?xml version="1.0" encoding="UTF-8" ?>')
CS.CAT('<13,10><<structure>')
CS.Cat('<13,10><<program title="' & ANSI2HTML(Loc:MName) & '"/>')
LOOP ManQ# = 1 to Records(ManQ)
Get(ManQ, ManQ#)
CS.Cat('<13,10><<topic level="' & ManQ:Level |
& '" id="' & Clip(ManQ:ID) & '" name="' & ANSI2HTML(ManQ:Name) & '" />')
END
CS.Cat('<13,10><</structure>')
CS.ToUTF8()
CS.SaveToFile(Loc:ManifestFileName)
EXIT
XML C8 - не понял...
Не удается прикрутить код, Юрий! В глобальных вставках пишу Include('...'), в процедуре обьявляю переменную типа CStr. Приложение - multiDLL + EXE.
При первом же вызове процедуры из основного фрейма - AV...
Убираю декларацию переменной - процедура работает. А толку? В чем затык? Так сказать, в чем нюанс?..
При первом же вызове процедуры из основного фрейма - AV...
Убираю декларацию переменной - процедура работает. А толку? В чем затык? Так сказать, в чем нюанс?..
-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
Я помещаю Include ('cstr.inc') в глобальную секцию данных, потом добавляю драйвер DOS, если нужно. И всё работает.
Куча приложений от CW5 до СW9 функционируют
Скорее всего, XML не в UTF-8.
Пришли, плиз, свой XML на yufil@mail.ru или на padreyufil@gmail.com, посмотрю
Куча приложений от CW5 до СW9 функционируют
Скорее всего, XML не в UTF-8.
Пришли, плиз, свой XML на yufil@mail.ru или на padreyufil@gmail.com, посмотрю
XML C8 - не понял...
да, все так и сделано. и драйвер ДОС добавлен. Но дело не доходит вообще до работы с файлами - процедура тупо валится на этапе инициализации, если обьявлена переменная типа cstr - то есть валится даже не на первом операторе, а где-то раньше...
-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
Если падает при объявлении, значит глючит конструктор, поставьте дебаг туда. Но там всё настолько очевидно...
Self.S &= New CString(2)
Self.S = ''
Self.Len=0
Или попробуйте вместо
CS Cstr
написать CS Class(Cstr)
END
Или даже
СS &Cstr
CS &= New Cstr
....
Dispose(CS)
Правда, с CW8 не работал, как-то он у меня не пошёл...
Self.S &= New CString(2)
Self.S = ''
Self.Len=0
Или попробуйте вместо
CS Cstr
написать CS Class(Cstr)
END
Или даже
СS &Cstr
CS &= New Cstr
....
Dispose(CS)
Правда, с CW8 не работал, как-то он у меня не пошёл...
XML C8 - не понял...
С этого и начал. Не доходит даже до первого оператора...7 Май 2015, 7:02
Если падает при объявлении, значит глючит конструктор, поставьте дебаг туда. Но там всё настолько очевидно...
Это было второй попыткой. Компилиться не захотел...Или даже
СS &Cstr
Вот это попробую. Хотя как-то мудрено... Тот же ХМЛ класс при обьявлении переменных ведет себя нормально...написать CS Class(Cstr)
END
-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
УРА! Как ни странно, такое обьявление переменной пришлось кларе по душе! ASCII-XML файл считан!!! И даже по-русски выводит! Код следующий:
Надеюсь память из-под CS высвобождать вручную не надо?
Ну теперь завтра займемся выковыриванием из ListXML атрибутов
Вроде судя по коду ViewXML это не особенно сложно.
Спасибо, Юрий! И всем, принимающим участие в дискуссии тоже спасибо!
Код: Выделить всё
Doc &= XMLStringToDOM(CS.S)
If Doc &= null Then Message('Aaaa!!!')
End
FillDOMQueue(Doc, ListXML)
Loop I# = 1 To Records(ListXML)
Get(ListXML, I#)
CS.Set(ListXML.node.GetNodeValue())
CS.ToASCII()
Stop(ListXML.level & ' - ' & ListXML.node.GetNodeName() & ' - ' & CS.S & ' - ' & ListXML.node.GetNodeType())
End
If not Doc &= null Then Doc.Dispose() End
Ну теперь завтра займемся выковыриванием из ListXML атрибутов

Спасибо, Юрий! И всем, принимающим участие в дискуссии тоже спасибо!
-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
Усердие всё превозмогает (К.Прутков) 
А разборку строки с параметрами в этой ветке форума я уже давал, поищи чуть повыше...

А разборку строки с параметрами в этой ветке форума я уже давал, поищи чуть повыше...
XML C8 - не понял...
Кстати, не совсем правильный алгоритм.
Сначала надо запросить имя тэга через GetNodeName (кстати, он тоже в UTF-8, если допускаются русские теги, то и его надо перекодировать), а потом, в зависимости от NodeName, уже разбирать строку, пример выше.
Ну и Doс надо освободить в конце, командой
Doc.Release()
Кусок из реальной программы...
Некий файл (манифест) считывается в очередь ManQ
Сначала надо запросить имя тэга через GetNodeName (кстати, он тоже в UTF-8, если допускаются русские теги, то и его надо перекодировать), а потом, в зависимости от NodeName, уже разбирать строку, пример выше.
Ну и Doс надо освободить в конце, командой
Doc.Release()
Кусок из реальной программы...
Некий файл (манифест) считывается в очередь ManQ
Код: Выделить всё
LoadManifest ROUTINE ! Загрузка манифеста
DATA
xmlDoc &Document,Auto
Nl &Nodelist,Auto
nnm &NamedNodeMap,auto
ANode &Node,Auto
AttrIndex Long
ListXML queue(DOMQueue) ! Очередь для считывания параметров
end
! ! Создадим пустой манифест
! CS.Set('<<?xml version="1.0" encoding="UTF-8" ?>')
! CS.CAT('<13,10><<structure>')
! CS.Cat('<13,10><<program title="Наименование проекта"/>')
! CS.Cat('<13,10><<topic level=0 id="ГЛМЕНЮ" name="Главное меню" />')
! CS.Cat('<13,10><</structure>')
CODE
Ret# = CS.LoadFromFile(Loc:ManifestFileName)
If Ret#
Message('Ошибка загрузки манифеста ' & Loc:ManifestFileName )
Exit
End
XmlDoc &= XmlStringToDom(CS.S)
If XMLDoc &= Null
Message('Ошибка разборки манифеста ' & Loc:ManifestFileName )
EXIT
End
FillDomQueue(XMLDoc,ListXML,1)
FREE(ManQ)
LOOP ListXML# = 1 to Records(ListXML)
Get(ListXML, ListXML#)
CASE lower(ListXML.Node.getNodeName())
OF 'topic'
nnm &= ListXML.Node.getAttributes()
IF not nnm &= null
Loop AttrIndex = 0 to nnm.getLength() - 1
Anode &= nnm.item(AttrIndex)
CS.Set(Anode.GetNodeValue())
CS.ToAscii()
Case lower(ANode.GetNodename())
Of 'level' !
ManQ:Level = CS.S
OF 'id'
ManQ:ID = Clip(CS.S)
OF 'name'
ManQ:Name = Clip(CS.S)
END
END
ADD(ManQ)
END
OF 'program'
nnm &= ListXML.Node.getAttributes()
IF not nnm &= null
Loop AttrIndex = 0 to nnm.getLength() - 1
Anode &= nnm.item(AttrIndex)
CS.Set(Anode.GetNodeValue())
CS.ToAscii()
Case lower(ANode.GetNodename())
Of 'title' !
Loc:MName=CS.S
END
END
END ! If nnm &= Null
END ! Case NodeName
END ! Loop ListXML#
XMLDoc.Release()
Display()
EXIT
XML C8 - не понял...
Именно так (т.е. почти команда-в-команду!!!) и получилось 
Не понял только, зачем Display() в конце. Вроде по коду никаких экранных переменных не наблюдается. А EXIT в конце роутины как дань порядку?

Не понял только, зачем Display() в конце. Вроде по коду никаких экранных переменных не наблюдается. А EXIT в конце роутины как дань порядку?

-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
Радостная эйфория четверга от продвинувшегося изучения XML и Cstr неожиданно сменилась пятничным разочарованием под стать московской погоде пятничного вечера. Оказалось, что всплыло море подводных камней следующего плана.
1. "Странное" обьявление переменной типа
CS Class(Cstr)
End
решило проблему РОВНО наполовину, ибо проблема теперь возникает в противоположном месте - процедура падает с AV при выходе из нее. Как я понимаю, при вызове деструктора. Однако, как и в случае с конструктором, дело не доходит даже до первого оператора метода. Подозреваю, что проблема все-таки в синтаксисе. На данный момент выкрутился, переименовав методы на Prepare() и UnPrepare() соответственно и вызывая их в начале и в конце процедуры. Не знаю, правильно ли это?
Теперь о наблюдениях...
2. Перенос обьявления переменной типа Cstr в секцию глобальных переменных, как ни странно, позволяет обьявить переменную нормальным способом:
CS Cstr
однако теперь AV будет вываливаться не в конце процедуры, а на выходе из программы. Видимо, т.к. схема ЕХЕ+мультиДЛЛ полагает статическую линковку дилелей, то и разынициализация происходит при завершении приложения в целом;
2. Если сменить обьявление класса с
cstr class,type,module('cstr.clw'),link('cstr.clw')
на
cstr class,type,module('cstr.clw'),link('cstr.clw',_cstrLinkMode_),dll(_cstrLinkMode_),
то 'нормальным' способом обьявить переменную удается даже в секции локальных данных. Правда, прм этом программа валится уже не на инициализации, а при первом обращении к этой переменной, т.е.
cs.loadfromfile(...)
Прошу помощи в разборе данной проблемы.......
Существует еще интересная штука, связанная с утечкой памяти при работе ХМЛ класса кларика, но об этом чуть позже - пора мыть ребенка
))
1. "Странное" обьявление переменной типа
CS Class(Cstr)
End
решило проблему РОВНО наполовину, ибо проблема теперь возникает в противоположном месте - процедура падает с AV при выходе из нее. Как я понимаю, при вызове деструктора. Однако, как и в случае с конструктором, дело не доходит даже до первого оператора метода. Подозреваю, что проблема все-таки в синтаксисе. На данный момент выкрутился, переименовав методы на Prepare() и UnPrepare() соответственно и вызывая их в начале и в конце процедуры. Не знаю, правильно ли это?
Теперь о наблюдениях...
2. Перенос обьявления переменной типа Cstr в секцию глобальных переменных, как ни странно, позволяет обьявить переменную нормальным способом:
CS Cstr
однако теперь AV будет вываливаться не в конце процедуры, а на выходе из программы. Видимо, т.к. схема ЕХЕ+мультиДЛЛ полагает статическую линковку дилелей, то и разынициализация происходит при завершении приложения в целом;
2. Если сменить обьявление класса с
cstr class,type,module('cstr.clw'),link('cstr.clw')
на
cstr class,type,module('cstr.clw'),link('cstr.clw',_cstrLinkMode_),dll(_cstrLinkMode_),
то 'нормальным' способом обьявить переменную удается даже в секции локальных данных. Правда, прм этом программа валится уже не на инициализации, а при первом обращении к этой переменной, т.е.
cs.loadfromfile(...)
Прошу помощи в разборе данной проблемы.......
Существует еще интересная штука, связанная с утечкой памяти при работе ХМЛ класса кларика, но об этом чуть позже - пора мыть ребенка

-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
С памятью в ХМЛ по моим наблюдениям дело тоже швах.
1. В предложенном Yufil коде при многократной обработке файла большого обьема размер выделяемой памяти непрерывно растет. Можно сделать
nnm.release() в конце каждого цикла, где nnm &NamedNodeMap. Это устраняет прирост занимаемой памяти.
2. Однако!
Doc &= XMLStringToDom(CS.S)
Doc.Release()
не дает роста памяти, а вот если между операторами вставить
FillDOMQueue(...),
то отжирается приличный кусман памяти (в моем случае большого файла - около 40 кб), и не высвобождается до конца работы приложения. Правда, и прироста в дальнейшем повторном вызове не наблюдается...
В чем дело?... В очереди остаются обьекты?
1. В предложенном Yufil коде при многократной обработке файла большого обьема размер выделяемой памяти непрерывно растет. Можно сделать
nnm.release() в конце каждого цикла, где nnm &NamedNodeMap. Это устраняет прирост занимаемой памяти.
2. Однако!
Doc &= XMLStringToDom(CS.S)
Doc.Release()
не дает роста памяти, а вот если между операторами вставить
FillDOMQueue(...),
то отжирается приличный кусман памяти (в моем случае большого файла - около 40 кб), и не высвобождается до конца работы приложения. Правда, и прироста в дальнейшем повторном вызове не наблюдается...
В чем дело?... В очереди остаются обьекты?
-------------------------------
В истинном золоте блеска нет...
В истинном золоте блеска нет...
XML C8 - не понял...
Ну, можно по концу очередь очистить, если есть желание. А новых объектов там быть вроде не должно. Насколько я понимаю, дерево разборки возвращает ссылки на разные места XML-текста, но не сами данные.
Что касается возврата памяти - а кто сказал, что память возвращается сразу? Обычно приложение имеет некий локальный пул памяти, а потом уже, при нехватке места, запрашивает дополнительную память у Windows. И 40К памяти на 18-мегабайтный файл - оно как-то не впечатляет.
А вот глюки с объектами Cstr очень странны, этот класс давно сделан и давно работает, правда, под CW5 и CW55 слегка урезается. Ну и пару
сомнительных мест уже лет пять как хочу поправить. Например, при конвертации в UTF-8 я считаю, что строка Unicode и UTF-8 в два раза длиннее исходной, а это не всегда так. Константу 1251 в тех же функциях заменить на вызов GetACP(), возвращающей текущую кодовую страницу.
Что касается возврата памяти - а кто сказал, что память возвращается сразу? Обычно приложение имеет некий локальный пул памяти, а потом уже, при нехватке места, запрашивает дополнительную память у Windows. И 40К памяти на 18-мегабайтный файл - оно как-то не впечатляет.
А вот глюки с объектами Cstr очень странны, этот класс давно сделан и давно работает, правда, под CW5 и CW55 слегка урезается. Ну и пару
сомнительных мест уже лет пять как хочу поправить. Например, при конвертации в UTF-8 я считаю, что строка Unicode и UTF-8 в два раза длиннее исходной, а это не всегда так. Константу 1251 в тех же функциях заменить на вызов GetACP(), возвращающей текущую кодовую страницу.