【问题标题】:How to set XML parser's Decimal point character?如何设置 XML 解析器的小数点字符?
【发布时间】:2014-03-16 00:51:34
【问题描述】:

我正在读取 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(),但这将为 ALL 应用程序设置格式。 getlocale() 函数操作当前线程,但我还没有找到明确指定要使用的字符的方法。似乎只能选择代码页或本地化,就像在一个国家/地区一样。

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

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

【问题讨论】:

  • (这不是一个标准的 XML 问题,它是专门针对 Microsoft 而不是可移植的。所以我的回答并不直接适用,我会向您推荐 Microsoft。)

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


【解决方案1】:

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

NodeValue 属性获取器返回一个 OleVariant,其中包含作为 String 的属性值,而不是作为 float。然后,您将 OleVariant 分配给 float。 RTL 使用 OS 区域设置执行转换,而不是 RTL 定位设置,这就是 FormatSettings 无效的原因。

NodeValue 属性设置器接收 OleVariant 作为输入。在将值插入 XML DOM 时,将 float 直接传递给它会执行到 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);

【讨论】:

  • 感谢您的深入解释。我最终得到了与您的建议类似的字符串转换。你确认不是我失败了;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-27
  • 2011-01-04
  • 2012-06-09
  • 1970-01-01
  • 1970-01-01
  • 2016-10-06
相关资源
最近更新 更多