Текущий архив: 2006.10.29;
Скачать: CL | DM;
Вниз
XML разделитель Найти похожие ветки
← →
REA (2006-09-12 15:59) [0]При записи в XML через TXMLDocument на одной машине системный разделитель (чисел с плавающей точкой) запятая.
На другой - точка и соответственно не читается.
Как с этим бороться?
← →
Reindeer Moss Eater © (2006-09-12 16:32) [1]Заменить точку на запятую или наоборот.
← →
Loginov Dmitry © (2006-09-12 16:52) [2]Используй DecimalSeparator
← →
Fay © (2006-09-12 22:32) [3]2 Loginov Dmitry © (12.09.06 16:52) [2]
Как именно предполагается его использовать?
DecimalSeparator - просто какой-то символ.
← →
REA (2006-09-13 11:02) [4]И где там в TXMLDocument этот Decimal Separator?
>Заменить точку на запятую или наоборот.
Вручную что ли? А для чего тогда вообще этот XML, если парсинг вручную делать?
← →
Slym(RO) (2006-09-13 11:32) [5]Не пользуй Борландовский TXMLDocument, пользуй Микрософтовый CreateOleObject("MSXML.DOMDocument")
← →
REA (2006-09-13 11:45) [6]>2Slym(RO)
А чем оно принципиально отличается? Мне кажется там просто обертка.
← →
Reindeer Moss Eater © (2006-09-13 11:58) [7]Вручную что ли? А для чего тогда вообще этот XML, если парсинг вручную делать?
Кто тебе здесь сказал про ручной парсинг?
← →
umbra © (2006-09-13 12:47) [8]
> При записи в XML через TXMLDocument на одной машине системный
> разделитель (чисел с плавающей точкой) запятая.
> На другой - точка и соответственно не читается.
в каком смысле не читается? насколько я знаю, XML без DTD или схемы ничего не знает ни о каких типах, и ему глубоко плевать, точка стоит в значении элемента или запятая.
← →
Reindeer Moss Eater © (2006-09-13 12:54) [9]Все очень просто.
У него в приложении переменная и он работает с содержимым нода как с вариантом, присваивая значение нода или атрибута даблу.
дециамал сеператаор на машине-источнике документа и на машине приемнике разные. Отсюда и засада.
Причем здесь сам XML документ - непонятно. Тема верится вокруг банального StrToFloat
← →
REA (2006-09-14 11:18) [10]>2Reindeer Moss Eater
Предлагаешь вытащить в строку и StrToFloat сделать самому?
Можно пожалуй и так, но я думал там где нибудь есть встроенное средство.
А что в стандарте то по этому поводу?
DTD у меня действительно никакого нет.
← →
Reindeer Moss Eater © (2006-09-14 11:20) [11]Нет не предлагаю. Где у меня написано, что я такое предлагаю?
Читай что у меня написано.
← →
REA (2006-09-14 11:29) [12]Написано "Заменить точку на запятую или наоборот."
Звучит неоднозначно... Где менять то?
← →
Reindeer Moss Eater © (2006-09-14 11:35) [13]Ты : на одной машине системный разделитель (чисел с плавающей точкой) запятая.
На другой - точка
Я : Заменить точку на запятую или наоборот.
Вроде предельно по-русски и предельно ясно.
← →
umbra © (2006-09-14 12:08) [14]по-моему, лучше всего при создании XML записывать текущий
DecimalSeparator
в него же, а при обработке читать из файла, и если обрабатывающая прога пишется на Д7 и больше, то использоватьGetLocaleFormatSettings
, а если меньше, то сравнимать разделитель из файла с текущим, и если они разные, то читать данные как строки, заменять разделитель и потом конвертировать в число.
← →
REA (2006-09-14 12:58) [15]>Вроде предельно по-русски и предельно ясно.
Не совсем. Там используется насколько я понимаю OleVariant-ы.
Если заменить переменную decimal separator на преобразования это не повлияет. Если преобразовать до присвоения Node в строку, то скорее всего сработает, но это несколько грубоватое решение.
← →
REA (2006-09-14 13:00) [16]>2Reindeer Moss Eater
При всем моем уважении иногда имеет смысл давать развернутые ответы на обозначенные вопросы, а не заставлять "читать мои труды".
← →
simpson © (2006-09-14 13:02) [17]По-моему, лучше всего при использовании XML строго оговаривать формат XML-документа, в том числе и какой decimal separator использовать. ;)
← →
Slym(RO) (2006-09-14 13:08) [18]Кто мешает в XML засунуть тег определяющий DecimalSeparator?
<?xml version="1.0" encoding="Windows-1251" DecimalSeparator="." ?>
А в коде выделять его и перед загрузкой DecimalSeparator:=XML.Atrib["DecimalSeparator"];
← →
Reindeer Moss Eater © (2006-09-14 13:08) [19]Если заменить переменную decimal separator на преобразования это не повлияет.
Тогда ты что-то странное говоришь:
На то, какой разделитель попадает в файл при формировании якобы влияет decimalseparator. И одновременно его смена на приемной машине не влияет на преобразование из OleVarianta.
← →
Reindeer Moss Eater © (2006-09-14 13:17) [20]Причина в чем-то другом.
Например в том, что при рождении документа ноду val могли присвоить строковое значение с разделителем-точкой (сами преобразовали и записали как строку)
Вот пример со сменой разделителей.
procedure TForm1.Button1Click(Sender: TObject);
var val : Double; cStr : string;
begin
DecimalSeparator := "."; ThousandSeparator := " ";
XMLDocument1.Active := True;
XMLDocument1.AddChild("test").Attributes["val"] := 12.34;
ShowMessage(XMLDocument1.xml.Text);
DecimalSeparator := ",";
XMLDocument1.ChildNodes.Nodes["test"].Attributes["val"] := 12.34;
ShowMessage(XMLDocument1.xml.Text);
val := XMLDocument1.ChildNodes.Nodes["test"].Attributes["val"];
ShowMessage(Format("%10.2f",[val]));
DecimalSeparator := ".";
val := XMLDocument1.ChildNodes.Nodes["test"].Attributes["val"];
ShowMessage(Format("%10.2f",[val]));
end;
← →
atruhin © (2006-09-14 13:40) [21]> [20] Reindeer Moss Eater © (14.09.06 13:17)
Только не забыть перед этим запомнить предыдущее значение и после восстановить.
← →
Reindeer Moss Eater © (2006-09-14 13:44) [22]В данном случае он действительно не влияет на запись/чтение из xml.
При любом разделителе у меня пишется запятая.
И при любом разделителе значение из нода попадает в дабл без проблем.
← →
REA (2006-09-14 13:48) [23]>Reindeer Moss Eater © (14.09.06 13:17) [20]
Первый и второй ShowMessage выводит с точкой. Т.е. DecimalSeparator как и ожидалось не влияет на преобразование.
Разумеется при обратном преобразовании из Double в строку будет использован DecimalSeparator, но до этого момента просто не дойдет, т.к. при попытке преобразовать из OleVariant (который будет воспринят как строка) вывалится Exception.
Так что мне бестолковому делать то?
← →
REA (2006-09-14 13:49) [24]Потому что эксперимент поставлен не в чистом виде. Надо записать на диск, поменять разделитель и попытаться прочитать.
← →
Reindeer Moss Eater © (2006-09-14 13:52) [25]При записи в файл происходит то же самое.
Какой бы ни был сепаратор, попадает запятая.
← →
Reindeer Moss Eater © (2006-09-14 13:54) [26]На том конце при формировании документа ноду или атрибуту присвоили не дабл, а строку.
← →
REA (2006-09-14 14:29) [27]Поправочка - какой бы ни был Delphi сепаратор попадает системный сепаратор. Присваивается там дабл.
← →
REA (2006-09-14 16:16) [28]>Кто мешает в XML засунуть тег определяющий DecimalSeparator?
А сымсл?
← →
umbra © (2006-09-14 16:35) [29]2 REA (14.09.06 16:16) [28]
чтобы сделать у себя такой же
← →
Reindeer Moss Eater © (2006-09-14 16:37) [30]Умбра, не влияет decimalseparator на чтение из файла. Не влияет.
Мой пример это демонстрирует.
← →
umbra © (2006-09-14 17:36) [31]тогда я вообще не понимаю в чем, собственно проблема. К Вашему коду я добавил строки
XMLDocument1.SaveToFile("test.xml");
DecimalSeparator := ",";
XMLDocument1.LoadFromFile("test.xml"); //здесь поставил точку прерывания
val := XMLDocument1.ChildNodes.Nodes["test"].Attributes["val"];
исправил в файле запятую на точку и не получил исключения!
← →
umbra © (2006-09-14 20:35) [32]вроде разобрался.
2 Reindeer Moss Eater © (14.09.06 16:37) [30]
зачем нам вообще запись в файл, если проблемы с чтением
REA (14.09.06 16:16) [28]
пусть у нас есть xml-файл такого содержания<test separator="a">12a34</test>
Значение тэга можно преобразовать вdouble
без всяких проблем.
Напрмерprocedure TForm1.Button1Click(Sender: TObject);
var
mynode: IXMLNode;
separator : String;
val : double;
oldseparator: char;
begin
XMLDocument1.LoadFromFile("test.xml");
mynode := XMLDocument1.ChildNodes.Nodes["test"];
oldseparator := DecimalSeparator;
separator := mynode.Attributes["separator"];
DecimalSeparator := separator[1];
val := mynode.NodeValue;
DecimalSeparator := oldseparator;
ShowMessage(FloatToStr(val *10));
end;
← →
Slym(RO) (2006-09-15 03:56) [33]separator[1]; - AV в подарок
Copy(separator,1,1)!
← →
umbra © (2006-09-15 10:00) [34]
> separator[1]; - AV в подарок
каким образом?
← →
Slym(RO) (2006-09-15 10:08) [35]может оказаться что length(separator)=0
← →
umbra © (2006-09-15 10:32) [36]в общем случае, конечно, да. Но это ж только иллюстрация на известных данных.
К тому же, еслиlength(separator)=0
, то нет никакого смысла копировать из памяти неизвестно что в качестве разделителя. :)
← →
Slym(RO) (2006-09-15 10:56) [37]umbra © (15.09.06 10:32) [36]
на известных данных
все программы тестируются на известных данных, а после финального релиза и установки на N компах частота телефонных звонков =N*M, где M- количество строк separator[1]
← →
REA (2006-09-15 15:01) [38]Да не влияет DecimalSeparator ни на запись ни на чтение т.к. он играет роль только при StrToFloat, а в случает SomeDouble := SomeOleVariantбудет в зависимости от типа либо преобразование либо Exception (если там строка).
А хочется чтобы формат XML не зависел от разделителя и писался однообразно. Нет ли там в стандарте XML разделителя?
← →
umbra © (2006-09-15 16:04) [39]
> Да не влияет DecimalSeparator ни на запись ни на чтение
не влияет, но при запуске программы изDecimalSeparator
можно узнать, какой разделитель используется в системе, а значит, и какой будет записан в файл.
> SomeOleVariant
насколько я понял, при чтении из xml этот вариант всегда будет OleString. И именно от текущего DecimalSeparator зависит, будет исключение при преобразовании строки в Double или нет.
> А хочется чтобы формат XML не зависел от разделителя и писался
> однообразно.
Стандарт XML этого не предусматривает. Об этом должны позаботиться Вы путем указания разделителя, использованного при создании файла в самом этом файле. Если это по каким-то причинам невозможно, то Вам придется узнавть этот разделитель самому, например, прочтя значение элемента, которое должно быть представлением числа, поискать в нем символы-нецифры.
← →
Ketmar © (2006-09-15 16:12) [40]что интересно -- давно ответили про Locale Settings. чего мусолить -- не понимаю. то, что изменение DecimalSeparator не меняет установок локали -- очевидно из исходников генофонда. то, что варианты преобразовывает система, которая знать не знает ни о каком DecimalSeparator -- очевидно после некоторых размышлений. осталось только свести эти два факта воедино.
← →
REA (2006-09-15 16:31) [41]Записать, прочитать разделитель можно, но преобразовывать то все равно вручную придется, а раз так, то можно и писать с точкой и читать с точкой, но это все дополнительные манипуляции.
Если нет других вариантов, придется читать как строку и потом делать StrToFloat. И еще заодно проверять на NAN.
← →
umbra © (2006-09-15 16:37) [42]а чем umbra © [32] не устраивает?
← →
REA (2006-09-15 16:42) [43]val := mynode.NodeValue; влепит Exception
← →
umbra © (2006-09-15 17:23) [44]var
NewDecSeparator, OldDecSeparator: Char;
buf: String;
{.......................................}
function FindSeparator(val: string): Char;
var
i, count: integer;
begin
count := 0;
for i := 1 to length(val) do
if (ord(val[i]) < 48) or (ord(val[i]) > 57) then//если это не цифра
begin
Result := val[i];
Inc(count);
end;
if count <> 1 then//слишком много или слишком мало разделителей
Result := "0";
end;
{..............................................................}
//берете первый попавшийся элемент, значение которого должно быть числом с //плавающей точкой.
mynode := XMLDocument1.ChildNodes.Nodes["ShouldBeDouble"];
buf := mynode.NodeValue;
try
val := mynode.NodeValue;
except
on EVariantTypeCastError do
NewDecSeparator := FindSeparator(buf);
end;
if NewDecSeparator <> "0" then
begin
OldDecSeparator := DecimalSeparator;
DecimalSeparator := NewDecSeparator;
end;
после этогоval := mynode.NodeValue;
вызывать исключения не будет
← →
REA (2006-09-15 17:33) [45]Вместо всего этого лучше всегда писать с точкой и читать с точкой. К тому же исключения на больших объемах будут сильно тормозить.
Я думал какое то стандартное решение есть - формат то достоточно универсальный. А вручную разумеется можно сделать преобразования.
← →
umbra © (2006-09-15 17:41) [46]
> К тому же исключения на больших объемах будут сильно тормозить.
это делается один раз для определения разделителя, использованного при записи файла. Затем можно спокойно обрабатывать весь файл. После обработки надо вернуть назад старый разделитель, открыть следующий файл и повторить процедуру.
← →
REA (2006-09-15 17:48) [47]>Затем можно спокойно обрабатывать весь файл
как обрабатывать? DecimalSeparator как уже неоднократно говорилось не влияет на преобразование.
← →
sniknik © (2006-09-15 17:56) [48]> К тому же исключения на больших объемах будут сильно тормозить.
если тормоза для обмена критичны, то ты выбрал не тот формат для него...
> формат то достоточно универсальный.
это только мечты маркетологов из мелкософта. не знаю в чем у тебя проблема (не сталкивался) но до универсальсти xml-ю очень далеко. (да и не бывает такого, это все одно, что машина универсал - типа и феррари обгонит, и груза больше белаза увезет, а если дороги нет то низко полетит... бред)
← →
sniknik © (2006-09-15 17:58) [49]http://delphimaster.net/view/3-1158153248/
← →
umbra © (2006-09-15 18:26) [50]
> DecimalSeparator как уже неоднократно говорилось не влияет
> на преобразование.
Кстати, хотя Reindeer Moss Eater © в [22] говорит, что во всех 4 сообщениях у него разделитель - запятая, у меня в четвертом сообщении стоит точка (Д7, msxml 4.0). И код из [32] у меня не вызывает исключений. На основе собственного опыта я вижу, чтоDecimalSeparator
не влияет на преобразование при записи в файл, но влияет на преобразование при чтении.
← →
REA (2006-09-18 11:00) [51]>если тормоза для обмена критичны, то ты выбрал не тот формат для него...
Согласен, формат не самый удобный, но пока что работает. Переписывать уже лень.
>На основе собственного опыта я вижу, что DecimalSeparator не влияет на преобразование при записи в файл, но влияет на преобразование при чтении.
Каким образом? Преобразование в OleVariant из текста делается похоже в библиотеке парсинга, а она про DecimalSeparator ничего не знает.
← →
umbra © (2006-09-18 11:49) [52]вы код из [32] пробовали выполнить?
← →
REA (2006-09-18 12:34) [53]И то верно - работает. Похоже класс замещает функцию преобразования из строки в число. Как бы теперь сделать, чтобы и наоборот тоже работало?
Страницы: 1 2 вся ветка
Текущий архив: 2006.10.29;
Скачать: CL | DM;
Память: 0.61 MB
Время: 0.032 c