如何设置XML解析器的小数点字符?

时间:2014-03-16 00:51:35

标签: xml c++builder decimal-point firemonkey-fm3 c++builder-xe5

我正在读取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文件是第三方文件,我无法控制。所以我真的需要用'.'小数分隔符

来读它

1 个答案:

答案 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);