-
Коллеги!
1. Меня тут старшие товарищи пристыдили, что пользуюсь доморощенным парсером XML вместо проверенного временем MSXML. Полностью согласен!
2. Сел читать про TXMLDocument. Какие-то локальные задачи на нем решал и ранее, но сейчас надо все по-серьезному (так называемый ЭДО наступает). Поэтому хочу изучить тему хорошо (как мастер дельфи ;-o).
3. Вопрос даже не по TXMLDocument, а по современным источникам информации по Дельфи. Что читать? Что сейчас считается достоверным светочем информации по Дельфи? docwiki.embarcadero.com? docs.embarcadero.com? штатная справка (у меня до сих пор Delphi2007). доп. ресурсы?
-
> Тимохов Дима © (14.06.16 01:11)
> > 1. Меня тут старшие товарищи пристыдили, что пользуюсь доморощенным > парсером XML вместо проверенного временем MSXML. Полностью > согласен!
тут надо отдельно пояснить, что TXMLDocument - это не парсер. Это обертка над несколькими парсерами, пока их 3 штуки http://community.embarcadero.com/blogs/entry/setting-the-default-xml-dom-in-delphi-xe7-1что касается производительности, там где она действительно нужна используем nativexml, к сожалению, обертки для TXMLDocument у него пока нет. > Delphi2007
в следующем году - 10 лет.
-
Поэтому хочу изучить тему хорошо (как мастер дельфи ;-o).
по сути главное отличие - поддержка xpath которая вместо навигационного подхода дает декларативный (sql-like) доступ к данным. а значит изучение темы сводится к двум методам selectsingleNode, selectNodes + синтаксис xpath
-
Лично я пользуюсь доморощенным xml-парсером (не выбрасывать же его) в перемешку с родным маздайным IHTMLDocument, читать про который надо, как водится, в МСДНе.
-
> Тимохов Дима © (14.06.16 01:11)
> 1. Меня тут старшие товарищи пристыдили, что пользуюсь доморощенным > парсером XML вместо проверенного временем MSXML. Полностью > согласен!
Я тоже иногда пользуюсь доморощенным парсером. Пусть он не умеет многого, но то, что мне нужно зато, он умеет как мне надо.
-
1. NativeXML. 1.1. Именно им и пользуюсь. Назвал его доморощенным в том смысле, что не общепринятый. 1.2. Сейчас пользуюсь версией 2.26. Все было хорошо лет 10, пока не встала четко задача с различными кодировками работать (до этого был только ANSI - его хватало для внутренних нужд). Начал разбираться, как он там умеет читать/писать в других кодировках... Но когда увидел код for i := 0 to cBomInfoCount - 1 do
begin
if cBomInfo[i].Enc = FEncoding then
begin
FWriteBom := cBomInfo[i].HasBOM;
break;
end;
end;
if FWriteBom then
FStream.WriteBuffer(cBomInfo[i].BOM, cBomInfo[i].Len);
, то мне несколько поплохело. Как это работает то вообще? Что это за шаманство с использованием i после цикла? Лажа! Естественно, полез смотреть более новые версии (3.32). Там этого безобразия уже нет (на while перешли, что логично). Но уж очень код отличается, да и справки я не нашел. А второй раз код просматривать этого NativeXML уже не хочется, чтобы разобраться. Поэтому и родилась идея изучить все же TXMLDocument. Это лирика была. Показать, что тоже пользуюсь NativeXML и, почему хочу отказаться. 1.3. Вопрос по NativeXML Кто какой версией пользуется? А нет ли проблем с кодировками при чтении/записи? 2. TXMLDocument. 2.1. Ок. понял. Справку копать. Думал, может есть статейка какая-нибудь классическая по теме.
-
2. TXMLDocument.
допустим на вход пришел xml документ. Известно, что нужное значение лежит в атрибуте "value" узла "unit" сам узел лежит на третьем или четвертом этаже вложенности от рута. причем их там несколько, а нужен тот, у которого в атрибуте "wanted" записано "1" и нет чайлдов с именем "deleted"
И используя для разбора такого документа TXMLDocument - программисту очень быстро станет грустно от навигационных методов доступа.
Это все равно что доставать данные из SQL сервера через TTable
-
> iop © (14.06.16 12:27) [6] >
Такие задачи бывают редко. Обычно интерес представляет весь документа или его большая часть. Мне понравилась потоковая обработка. Xml парсится и сразу "скармливается". Компонент не помню.
-
Такие задачи бывают редко.
насколько редки они бывают, чтобы сразу отказываться от xpath в пользу навигации?
мне например совсем недавно пришлось вынимать данные из xml, которые были сохраненными отчетами FR
в силу того, что структура заточена на отображение, и совершенно не заточена на "машинное чтение" я бы просто умер бы разбирая такие документы через TXMLDocument
Потоково - это конечно хорошо и для здоровья не вредно.
Но вот представь, что сто листов табличного отчета. часть данных лежит в строках (самый вложенный дитейл) а часть данных только в шапках таблиц.
Например на 20 странице начинаются данные по дому на улице ленина 1
и только в шапке 20 страницы есть данные об этом адресе. а дальше 10-15 страниц "обезличенных".
глаза такую превьюшку понимают конечно прекрасно, а машинный импорт - не очень.
и что бы я сказал в таком случае? прастите, такие задачи бывают не часто, поэтому я когжа-то давно решил не владеть xpath и сегодня не могу решить задачу в разумные сроки.
-
Вот простейший фрагмент для иллюстрации таблица с начислениями по лицевым счетам. начислений на один лицевой несколько, а сам лицевой только в первой строке. REM если лицевой пуст, то берем его из ближайшего предыдущего узла с непустым лицевым
if c_ls = "" then
dim node_before : set node_before = ANode.selectsinglenode("(preceding-sibling::b2[4 < string-length(m6/@u)])[last()]")
if not (node_before is nothing) then
c_ls = get_xpath_value(node_before,"./m6/@u")
c_addr = get_xpath_value(node_before,"./m4/@u")
end if
end if
пример конечно простейший, и так как недостает всего одного значения, то все можно решить потоковым парсером и одной глобальной переменной. но простейшие примеры - они редкие. чаще встречаются более замороченные случаи
-
У меня задача простая - читать/писать. Без XPath. Т.к. сам использовать не буду, надо подсунуть либу XML под обертку на моем же скриптовом языке. Т.е. нужно для прикладных разработчиков. Там уже есть механизм навигации.
Столкнулся с тем, что ранний NativeXML (им и пользуюсь), во-первых, как-то мутно работает с кодировками, во-вторых, просто содержит в коде лажу (привел выше). Доверия нет))
Вот проверенным методам (TXMLDocument) доверие есть. Но надо изучить.
Например, задался вопросами: 1. Как сохранять в заданной кодировке - ANSI, UTF-8, 16BE, 16LE и т.д. Пока не нашел. 2. Понимаю, что XML вроде как case sensitive. Но дабы не нарушать обратную совместимость, мне нужно case INsensitive. Тоже пока не нашел как сделать.
-
Например, задался вопросами: 1. Как сохранять в заданной кодировке - ANSI, UTF-8, 16BE, 16LE и т.д. Пока не нашел. 2. Понимаю, что XML вроде как case sensitive. Но дабы не нарушать обратную совместимость, мне нужно case INsensitive. Тоже пока не нашел как сделать.
не теми вопросами задаешься. кстати на xpath легко и непринужденно делается тот самый case Insensitive
но мы же не такие. мы трудности любим.
-
Вот проверенным методам (TXMLDocument) доверие есть. Но надо изучить.
Класс дебильнейший по сути. С одной стороны "память съем сразу и под весь дом целиком", но "икспаса не умею, не хочу и не дам"
успехов тебе в приобретении бесполезных навыков.
-
> iop © (14.06.16 13:22) [12]
Чот ты агрессивный какой-то)) Ок, спасибо. Буду думать.
-
> 1. Как сохранять в заданной кодировке - ANSI, UTF-8, 16BE, 16LE и т.д. Пока не нашел. IXMLDocument.Encoding:= 'windows-1251'; /utf-8
> 2. Понимаю, что XML вроде как case sensitive. Но дабы не нарушать обратную совместимость, мне нужно case INsensitive. Тоже пока не нашел как сделать. все одно раз делаешь фулскан/пробежку по всем веткам, то и сравнивай не по имени тега, а по UpperCase(имя тега).
кстати на размер xml-я он очень требовательный... не по детски, буквально 20 мег и обработчик зависает на неопределенное время на элементарных операциях типа Node:= MainNode.ChildNodes['channel'].NextSibling; (попытка взять второй элемент из первого тега "channel" в главной "ветке", да даже просто первый тег "channel" определить, это из разбора "безразмерной ленты RSS", сломалось где-то на размере 30 мегабайт, до этого было тормозно но терпимо по времени)
вообще xml как формат обмена данными очень переоценен... json не в пример лучше, если конечно все соблюдают правила формирования.
-
> sniknik © (14.06.16 14:11) [14] > IXMLDocument.Encoding:= 'windows-1251'; /utf-8
Да, ты прав. Что-то не углядел пока это свойство. Ща бьюсь с тем, что
Document := TXMLDocument.Create(nil);
Document.LoadFromFile(FileName);
не читает ANSI файл, в котором заголовок
<?xml version="1.0"?>
<root>...
т.е. без encoding... Выдает:
An invalid character was found in text content.
Line: 2
<.
Что, без encoding в ANSI вообще не читает?
-
> > 1.3. Вопрос по NativeXML Кто какой версией пользуется? А > нет ли проблем с кодировками при чтении/записи?
3.32 - новее по-моему не бывает уже. с кодировками проблем нет. в целом, какой может быть ANSI в 2016 году? заем создавать себе проблемы на пустом месте.
все бы хорошо с NativeXML, беда только в том, что нет кроссплатформенности.
> Document.LoadFromFile(FileName);
это вредная функция (по крайней мере, если память меня не подводит, с ней был ряд проблем, но было давно, лет 10 назад), вместо нее следует использовать LoadFromStream с указанием кодировки, проблем не замечал.
-
> Eraser © (14.06.16 15:42) [16] > это вредная функция (по крайней мере, если память меня не > подводит, с ней был ряд проблем, но было давно, лет 10 назад), > вместо нее следует использовать LoadFromStream с указанием > кодировки, проблем не замечал.
Похоже с RTF путаешь (стриминговая загрузка чтоб не поломался текст) - с XML вроде ровно было.
-
> не читает ANSI файл, в котором заголовок > <?xml version="1.0"?> по дефолту кодировка utf-8, определяется при чтении, при пере-присвоении в Encoding другой идет перекодировка.
-
> Eraser © (14.06.16 15:42) [16] > в целом, какой может быть ANSI в 2016 году? заем создавать > себе проблемы на пустом месте.
Ты предлагаешь все бросить и заняться портированием на уникод проекта, которым я занимаюсь 20 лет?))) Я когда-то это обязательно сделаю, но не сейчас. У меня и дельфи уже куплены несколько версий. Время не выберу. Поэтому ANSI - данность. Третья сторона может присылать, что угодно. Вот недавно дали файл без encoding в заголовке, но по факту в UTF-8. > 3.32 - новее по-моему не бывает уже. с кодировками проблем нет.
Может, я чего и не понимаю. Ты пойми, я делаю не для себя, а для разработчиков на скриптовом языке. Мне надо, чтобы работало максимально без проблем в независимости от того, какой файл будет дан в зубы - файлы формирует третья сторона. Скармливаю вот такой файл в кодировке ANSI:
<?xml version="1.0"?>
<корень атрибут_корня="значение атрибута корня">
</корень>
Вот такому коду:
kNX := TNativeXml.Create(nil);
kNX.LoadFromFile(FileName);
Вот ты как будешь получать имена тегов и атрибутов? Конкретно для этого файла вызовы
kNX.Root.NameUnicode
kNX.Root.AttributeValueByNameWide[sdAnsiToUtf8('атрибут_корня', 1251)]
Дают пустые строки, а вот вызовы
kNX.Root.Name
kNX.Root.AttributeValueByName['атрибут_корня']
При этом, если дать в зубы файл, где <?xml version="1.0" encoding="windows-1251"?> То работает ровно наоборот - первый набор вызовов дает верные значения, а второй - мусор. И вот как с этим работать?
|