0

我正在读取 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>

阅读属性比例后,我总是得到带有“。”的结果。导致 Value = 1234 而不是 1.234 的字符。

小数位数不是恒定的,它们可以是 1 或 4 或介于两者之间的任何值。这也适用于整个部分,因此除以 100 或 1000 不会解决问题。

我希望 OLEVariant 接受'.'小数点(我的本地是',')。

我看了看,SetLocalInfo()但这将为所有应用程序设置格式。该getlocale()函数操纵当前线程,但我还没有找到明确指定要使用的字符的方法。似乎只能选择代码页或本地化,就像在一个国家/地区一样。

编辑
我尝试使用setlocal()并选择English-US作为本地化。即使 US'.'用作小数点分隔符,XML 解析器似乎也忽略了这一点。

如果我在 XML 文件中手动将其更改'.'为 a ,它就可以正常工作。','但是 XML 文件是第三方文件,我无法控制。'.'所以我真的需要用小数分隔符阅读它

4

1 回答 1

4

IXMLNode.NodeValue这是属性处理浮点数的方式的一个众所周知的问题。它与底层 XML 引擎(MSXML 等)无关。

NodeValue属性 getter 返回一个OleVariant包含属性值的 a ,String而不是 a float。然后,您将其分配OleVariantfloat. RTL 使用 OS 区域设置执行转换,而不是 RTL 定位设置,这就是FormatSettings没有效果的原因。

属性设置器NodeValue接收一个OleVariant作为输入。在将值插入 XML DOM 时,将a 直接传递float给它会执行到 a 的转换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);
于 2014-03-18T01:03:21.850 回答