我正在读取XML文档中的属性字段,其中小数点始终为'.'
,而本地计算机可能与此不同(在我自己的情况下,它是','
)。
我尝试将全局FormatSettings.DecimalSeparator
设置为'.'
,但它对XML解析器没有影响。这是问题的一个非常压缩的版本。
_di_IXMLDocument Document;
_di_IXMLNode Node;
float Value;
Document = LoadXMLDocument("Test.xml");
Node = Document->DocumentElement;
FormatSettings.DecimalSeparator = '.';
Value = Node->GetAttribute("scale");
假设这个XML文件。
<?xml version="1.0" encoding="utf-8"?>
<myroot scale="1.234">
</myroot>
阅读完属性比例后,我总是会在&#39;上找到结果条纹。&#39;导致值= 1234而不是1.234的字符。
小数位数不是常数,它们可以是1或4或其间的任何内容。这也适用于整个部分,因此除以100或1000将无法解决问题。
我最好让OLEVariant接受'.'
作为小数点(我的本地是','
)。
我查看了SetLocalInfo()
,但这会设置 所有 应用程序的格式。 getlocale()
函数操作当前线程但我没有找到一种方法来显式指定要使用的字符。似乎只能在国家/地区选择代码页或本地化。
修改
我尝试使用setlocal()
并选择English-US
作为本地化。即使美国使用'.'
作为小数分隔符,XML解析器也似乎忽略了这一点。
如果我手动将'.'
更改为XML文件中的','
,则可以正常使用。但XML文件是第三方文件,我无法控制。所以我真的需要用'.'
小数分隔符
答案 0 :(得分:3)
这是IXMLNode.NodeValue
属性处理浮点数的方式的一个众所周知的问题。它与底层XML引擎(MSXML等)无关。
NodeValue
属性获取器返回OleVariant
,其中包含的属性值为String
,而不是float
。然后,您将OleVariant
分配给float
。 RTL使用操作系统区域设置执行转换,而不是RTL定位设置,这就是FormatSettings
无效的原因。
NodeValue
属性设置器接收OleVariant
作为输入。将float
直接传递给它会在将值插入XML DOM时转换为String
,并且该转换也不会与FormatSettings
绑定。
NodeValue
对语言环境敏感,但XML不是。 XML标准明确概述了必须如何格式化浮点数,IXMLNode
未考虑这些数字。因此,您必须将浮点值读/写为String
值,以便您可以自己处理转换,例如:
TFormatSettings fmt = TFormatSettings::Create();
fmt.DecimalSeparator = '.';
fmt.ThousandSeparator = 0;
Value = StrToFloat(Node->Attributes["scale"], fmt);
TFormatSettings fmt = TFormatSettings::Create();
fmt.DecimalSeparator = '.';
fmt.ThousandSeparator = 0;
Node->Attributes["scale"] = FloatToStr(Value, fmt);