Я использовал подготовленный XSD с помощью мастера привязки XML.
<?xml version="1.0" standalone="yes"?>
<xs:schema version="1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="examples" type="examples"/>
<xs:complexType name="examples">
<xs:sequence>
<xs:element name="example" type="example" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="example">
<xs:sequence>
<xs:element name="doublevalue" type="xs:double"/>
<xs:element name="decimalvalue" type="xs:decimal"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
Прежде всего, почему по умолчанию по-разному обрабатываются десятичные и двойные числа?
Простой XML-тип Double переводится в собственный тип Delphi Double, а простой XML-тип Decimal по умолчанию переводится в собственный тип Delphi UnicodeString.
У меня одинаковая проблема с обоими типами данных: конфликты локалей
Я немец.Это означает, что DecimalSeparator - ,
, а ThousandSeparator - .
по умолчанию (Windows).
Когда я читаю мой пример XML следующим образом, двойное значение 0,08 становится 8-целым числом.
XML
<?xml version="1.0" encoding="UTF-8"?>
<examples>
<example>
<doublevalue>0.08</doublevalue>
<decimalvalue>1001.015</decimalvalue>
</example>
</examples>
Код
var
xmldoc: IXMLDocument;
examples: IXMLExamples;
i: Integer;
d: Double;
begin
xmldoc := TXMLDocument.Create(nil) as IXMLDocument;
try
xmldoc.LoadFromFile('C:\temp\example.xml');
examples := Getexamples(xmldoc); // Getexamples() is part of the unit generated by the Binding Wizard
for i := 0 to examples.Count - 1 do
d := examples[i].Doublevalue;
finally
examples := nil;
xmldoc := nil;
end;
end;
Снимок
Сейчас я изменяю тип данных XML Double наСобственный тип Delphi UnicodeString и работа с методом, подобным следующему:
function XMLStringToDouble(const str: string): double;
var
fs: TFormatSettings;
begin
fs := FormatSettings;
fs.DecimalSeparator := '.';
fs.ThousandSeparator := #0;
result := StrToFloat(str, fs);
end;
При создании XML-кода
существует еще одна проблема
var
xmldoc: TXMLDocument;
examples: IXMLExamples;
example: IXMLExample;
begin
xmldoc := TXMLDocument.Create(nil);
try
xmldoc.DOMVendor := MSXML_DOM;
xmldoc.Options := [doNodeAutoCreate, doNodeAutoIndent, doAttrNull, doAutoPrefix, doNamespaceDecl];
xmldoc.Active := true;
xmldoc.Version := '1.0';
xmldoc.Encoding := 'UTF-8';
examples := xmldoc.GetDocBinding('examples', TXMLExamples, '') as IXMLExamples;
example := examples.Add;
example.Doublevalue := 0.08;
example.Decimalvalue := '1001.015';
xmldoc.SaveToFile('C:\temp\example.xml');
finally
xmldoc.Free
end;
end;
Я получаюXML с ,
в качестве десятичного разделителя.
<?xml version="1.0" encoding="UTF-8"?>
<examples>
<example>
<doublevalue>0,08</doublevalue>
<decimalvalue>1001.015</decimalvalue>
</example>
</examples>
1.Есть ли способ относиться к Double более простым / правильным образом?
2.Могу ли я как-то передать TFormatSettings в XMLDocument или решить его совершенно другим способом?
3.Как ты это делаешь?