You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

XmlMapper解析XML为JsonNode后,遍历transaction节点获取子节点异常的问题

XmlMapper解析XML为JsonNode后,遍历transaction节点获取子节点异常的问题

你遇到的这个问题我之前也碰到过,核心是XmlMapper对单个XML节点和数组节点的处理逻辑差异导致的,咱们一步步来梳理解决:

首先先提个小问题,你的XML代码里有个标签闭合错误:<order_ID>Test123456789</transaction_id>,这里的闭合标签应该是</order_ID>,先修正这个问题,不然解析时可能会出现额外异常。正确的XML结构应该是:

<order>
  <order_ID>Test123456789</order_ID>
  <original_inception_date>2024-09-25</original_inception_date>
  <transaction>
    <effective_date>2023-12-31 00:00:00.000</effective_date>
    <transaction_id>1a123456a1234a12345678ab12a1a12a</transaction_id>
    <product>123</product>
    <company>1</company>
    <lob>LIFE</lob>
  </transaction>
</order>

问题原因分析

当XML中只有单个<transaction>节点时,XmlMapper默认会将其解析为单个JsonNode对象,而不是JsonArray(数组)。这时候你用for(JsonNode forNode : node.get("transaction"))进行遍历,实际上是在遍历这个transaction节点的子节点(也就是effective_date、transaction_id这些字段节点),所以第一个forNode就是effective_date的节点,后续调用forNode.get("transaction_id")自然会找不到对应节点,抛出异常。

另外还有个细节:你代码里写的node.get("order_id"),但XML中的标签是<order_ID>,大小写必须严格匹配,否则会获取到null,这也是容易踩的坑。

解决方案

根据你的业务场景,有两种处理方式:

方式一:兼容单个/多个transaction节点

如果你的XML可能存在多个<transaction>节点,希望不管是单个还是多个都按数组逻辑处理,可以通过配置XmlMapper或者手动判断节点类型来实现:

XmlMapper xmlMapper = new XmlMapper();
// 全局配置:允许将单个值解析为数组,这样单个transaction也会被解析成数组
xmlMapper.enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);

JsonNode node = xmlMapper.readTree(xmlString);
JsonNode transactions = node.get("transaction");

for(JsonNode forNode : transactions) {
    // 注意order_ID的大小写匹配
    policyID = node.get("order_ID").asText();
    originalInceptionDate = node.path("original_inception_date").asText();
    transactionEffectiveDate = forNode.get("effective_date").asText();
    policyTransactionID = forNode.get("transaction_id").asText();
    product = forNode.get("product").asText();
    company = forNode.get("company").asText();
    lob = forNode.get("lob").asText();
    // 执行你的业务逻辑
}

如果不想全局配置,也可以手动判断节点是否为数组,再包装:

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xmlString);
JsonNode transactionNode = node.get("transaction");

// 手动处理单个节点的情况
JsonNode transactions;
if (transactionNode.isArray()) {
    transactions = transactionNode;
} else {
    transactions = xmlMapper.createArrayNode().add(transactionNode);
}

// 后续遍历逻辑同上

方式二:确定只有单个transaction节点

如果你的业务中XML永远只会有一个<transaction>节点,那完全不需要for循环,直接获取transaction节点后读取子字段即可:

XmlMapper xmlMapper = new XmlMapper();
JsonNode node = xmlMapper.readTree(xmlString);
JsonNode transactionNode = node.get("transaction");

policyID = node.get("order_ID").asText();
originalInceptionDate = node.path("original_inception_date").asText();
transactionEffectiveDate = transactionNode.get("effective_date").asText();
policyTransactionID = transactionNode.get("transaction_id").asText();
product = transactionNode.get("product").asText();
company = transactionNode.get("company").asText();
lob = transactionNode.get("lob").asText();

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.07 06:48:03