如何在Freemarker模板中以字符串形式读取大数字
解决Freemarker解析XML大数字精度丢失问题
问题根源
XML解析过程中,底层解析器会自动将节点内的数字文本转换为数值类型(如Java的Double或Long),而你的目标数值999910700212884131超过了64位浮点数的精确表示范围(2^53),导致存储和输出时出现精度丢失。
解决方案
1. 强制获取XML节点的原始文本字符串
在Freemarker模板中,直接通过XPath取值会触发自动类型转换,因此需要显式获取节点的文本内容,避免转换为数值类型。修改你的fix函数:
<#function fix arr> <#list arr as m> { <#assign node = m[".//D:MINIdentifier"][0]?node> <#assign field = node.text!'null'> <#if field != 'null' > <#return field> </#if> } </#list> </#function>
?node:明确将XPath结果转换为XML节点对象node.text:直接读取节点的原始文本内容,保留字符串格式,不会触发数值转换
2. 输出时包裹为JSON字符串
确保最终输出的JSON中该值以字符串形式存在,避免JSON解析器再次将其识别为数值。修改输出语句:
"MtgId ": "${fix(LOAN_IDENTIFIER)}"
3. 可选:配置XML解析器禁用自动类型转换
如果模板层面的处理仍有问题,可以在初始化XML数据源时,配置底层解析器禁止自动将文本转换为数值类型。例如使用Java代码初始化解析器时:
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); // 禁用自动类型转换,所有文本以字符串形式保留 factory.setFeature("http://apache.org/xml/features/dom/include-ignorable-whitespace", false); factory.setCoalescing(false); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc = builder.parse(xmlFile);
验证效果
修改后重新运行模板,输出的JSON将保留原始大数字的字符串形式:
"MtgId ": "999910700212884131"
内容的提问来源于stack exchange,提问作者VKP
相关产品推荐
相关产品推荐

