解析非标准xml字符串,转换为bean实体

开始之前我们先来看一下这个xml

<Response>
    <ResultCode>0</ResultCode>
    <ResultContent>查询成功!</ResultContent>
    <Schema>
        <ID>12345678</ID>
        <seeDate>2021/6/28 0:00:00</seeDate>
        <noonCode>2</noonCode>
        <deptCode>9001</deptCode>
        <deptName>普通外科门诊</deptName>
        <doctCode>3333</doctCode>
        <doctName>测试1</doctName>
        <reglevlCode>05</reglevlCode>
        <reglevlName>知名专家号</reglevlName>
        <beginTime>2021/6/28 11:30:00</beginTime>
        <endTime>2021/6/28 16:29:59</endTime>
        <RegedQTY>6</RegedQTY>
        <ghbz>1</ghbz>
        <regType>无号</regType>
        <RemainNo>0</RemainNo>
    </Schema>
    <Schema>
        <ID>12345679</ID>
        <seeDate>2021/6/28 0:00:00</seeDate>
        <noonCode>1</noonCode>
        <deptCode>9002</deptCode>
        <deptName>普通外科门诊</deptName>
        <doctCode>3334</doctCode>
        <doctName>测试2</doctName>
        <reglevlCode>05</reglevlCode>
        <reglevlName>知名专家号</reglevlName>
        <beginTime>2021/6/28 0:00:00</beginTime>
        <endTime>2021/6/28 11:29:59</endTime>
        <RegedQTY>8</RegedQTY>
        <ghbz>1</ghbz>
        <regType>无号</regType>
        <RemainNo>0</RemainNo>
    </Schema>
    <Schema>
        <ID>12345680</ID>
        <seeDate>2021/6/29 0:00:00</seeDate>
        <noonCode>1</noonCode>
        <deptCode>9003</deptCode>
        <deptName>普通外科门诊</deptName>
        <doctCode>3335</doctCode>
        <doctName>测试3</doctName>
        <reglevlCode>05</reglevlCode>
        <reglevlName>知名专家号</reglevlName>
        <beginTime>2021/6/29 0:00:00</beginTime>
        <endTime>2021/6/29 11:29:59</endTime>
        <RegedQTY>8</RegedQTY>
        <ghbz>1</ghbz>
        <regType>无号</regType>
        <RemainNo>0</RemainNo>
    </Schema>
</Response>

上面Response节点下有多个Schema,所以这个Schema应该是一个数组,正常来说需要用一个节点去包含一下,比如<Schemas><Schema></Schema><Schema></Schema>....</Schemas>这样,但是现在这个xml不是这个格式,所以在解析起来就比较麻烦了,用fasterxml解析就不行了,所以这个时候我们需要使用别的解析,我这里采用dom4j的方式解析

1、引入dom4j的jar依赖

<dependency>
   <groupId>dom4j</groupId>
   <artifactId>dom4j</artifactId>
   <version>1.6.1</version>
</dependency>

2、定义一个和Schema节点下的属性一样的实体bean

@Data
@Accessors(chain = true)
public class AppQueryValidResourceData implements Serializable {

        @JsonProperty("ID")
        private String id;

        @JsonProperty("seeDate")
        private String seeDate;

        @JsonProperty("noonCode")
        private String noonCode;

        @JsonProperty("deptCode")
        private String deptCode;

        @JsonProperty("deptName")
        private String deptName;

        @JsonProperty("doctCode")
        private String doctCode;

        @JsonProperty("doctName")
        private String doctName;

        @JsonProperty("reglevlCode")
        private String regLevelCode;

        @JsonProperty("reglevlName")
        private String regLevelName;

        @JsonProperty("beginTime")
        private String beginTime;

        @JsonProperty("endTime")
        private String endTime;

        /**
         * 已挂数量
         */
        @JsonProperty("RegedQTY")
        private int regNum;

        /**
         * 0.不显示 1.显示不控制时间 2. 8点整显示 3. 8:30显示 4. 0点显示
         */
        @JsonProperty("ghbz")
        private String ghbz;

        @JsonProperty("regType")
        private String regType;

        @JsonProperty("RemainNo")
        private int remainNo;

}

3、开始解析xml,直接上代码

private static List<AppQueryValidResourceData> parseSourceXml(String xml){
        List<AppQueryValidResourceData> resourceData = Lists.newArrayList();
        try {
            Document document = DocumentHelper.parseText(xml);
            Element root = document.getRootElement();
            Iterator iterator = root.elementIterator("Schema");
            while(iterator.hasNext()){
                AppQueryValidResourceData data = new AppQueryValidResourceData();
                Element next = (Element)iterator.next();
                data.setId(next.elementText("ID"));
                data.setSeeDate(next.elementText("seeDate"));
                data.setNoonCode(next.elementText("noonCode"));
                data.setDeptCode(next.elementText("deptCode"));
                data.setDeptName(next.elementText("deptName"));
                data.setDoctCode(next.elementText("doctCode"));
                data.setDoctName(next.elementText("doctName"));
                data.setRegLevelCode(next.elementText("reglevlCode"));
                data.setRegLevelName(next.elementText("reglevlName"));
                data.setBeginTime(next.elementText("beginTime"));
                data.setEndTime(next.elementText("endTime"));
                data.setRegNum(Integer.parseInt(next.elementText("RegedQTY")));
                data.setGhbz(next.elementText("ghbz"));
                data.setRegType(next.elementText("regType"));
                data.setRemainNo(Integer.parseInt(next.elementText("RemainNo")));
                resourceData.add(data);
            }
        } catch (DocumentException e) {
            log.error("parseSourceXml 异常,xml:{}", xml, e);
        }
        return resourceData;
    }

4、优化

如上所示,需要一个节点一个节点的解析,如果节点过多,或者增减可能就不好办了,这时候我们优化一下,如下:

private static List<AppQueryValidResourceData> parse(String xml){
        List<Map<String, Object>> list = parseXml(xml);
        if(CollectionUtils.isNotEmpty(list)){
            return JsonUtil.ofList(JsonUtil.toJson(list), AppQueryValidResourceData.class);
        }
        return Lists.newArrayList();
    }

    private static List<Map<String, Object>> parseXml(String xml) {
        List<Map<String, Object>> list = new ArrayList<>();
        try {
            Document document = DocumentHelper.parseText(xml);
            Element root = document.getRootElement();
            Iterator<Element> iterator = root.elementIterator("Schema");

            while (iterator.hasNext()) {
                Element ele = iterator.next();
                Map<String, Object> parenMap = new HashMap<>();
                child(ele, null, parenMap, null, null);
                list.add(parenMap);
            }
        } catch (DocumentException e) {
            log.error("parseSourceXml 异常,xml:{}", xml, e);
        }
        return list;
    }
    @SuppressWarnings("all")
    public static void child(Element ele, String keyName, Map<String, Object> parenMap, Map<String, Object> childMap,
            List<Map<String, Object>> childData) {
        Iterator<Element> childIter = ele.elementIterator();
        while (childIter.hasNext()) {
            Element attr = childIter.next();
            Iterator<Element> childIter2 = attr.elementIterator();
            if (childIter2.hasNext()) {
                Element attr2 = childIter2.next();
                Map<String, Object> childMap2 = new HashMap<>();
                List<Map<String, Object>> childData2 = new ArrayList<>();

                child(attr, attr.getName(), parenMap, childMap2, childData2);
            } else if (keyName != null) {
                childMap.put(attr.getName().trim(), attr.getText().trim());
            } else {
                parenMap.put(attr.getName().trim(), attr.getText().trim());
            }
        }
        if (keyName != null && childMap != null && !childMap.isEmpty()) {
            if (parenMap != null && parenMap.get(keyName) != null) {
                List<Map<String, Object>> object = (List<Map<String, Object>>) parenMap.get(keyName);
                object.add(childMap);
            } else {
                childData.add(childMap);
                parenMap.put(keyName, childData);
            }
        }
    }

5、测试

public static void main(String[] args) {
        String xml = "<Response><ResultCode>0</ResultCode><ResultContent>查询成功!</ResultContent><Schema><ID>12345678</ID><seeDate>2021/6/28 0:00:00</seeDate><noonCode>2</noonCode><deptCode>9001</deptCode><deptName>普通外科门诊</deptName><doctCode>3333</doctCode><doctName>测试1</doctName><reglevlCode>05</reglevlCode><reglevlName>知名专家号</reglevlName><beginTime>2021/6/28 11:30:00</beginTime><endTime>2021/6/28 16:29:59</endTime><RegedQTY>6</RegedQTY><ghbz>1</ghbz><regType>无号</regType><RemainNo>0</RemainNo></Schema><Schema><ID>12345679</ID><seeDate>2021/6/28 0:00:00</seeDate><noonCode>1</noonCode><deptCode>9002</deptCode><deptName>普通外科门诊</deptName><doctCode>3334</doctCode><doctName>测试2</doctName><reglevlCode>05</reglevlCode><reglevlName>知名专家号</reglevlName><beginTime>2021/6/28 0:00:00</beginTime><endTime>2021/6/28 11:29:59</endTime><RegedQTY>8</RegedQTY><ghbz>1</ghbz><regType>无号</regType><RemainNo>0</RemainNo></Schema><Schema><ID>12345680</ID><seeDate>2021/6/29 0:00:00</seeDate><noonCode>1</noonCode><deptCode>9003</deptCode><deptName>普通外科门诊</deptName><doctCode>3335</doctCode><doctName>测试3</doctName><reglevlCode>05</reglevlCode><reglevlName>知名专家号</reglevlName><beginTime>2021/6/29 0:00:00</beginTime><endTime>2021/6/29 11:29:59</endTime><RegedQTY>8</RegedQTY><ghbz>1</ghbz><regType>无号</regType><RemainNo>0</RemainNo></Schema></Response>";
        List<AppQueryValidResourceData> parse = parse(xml);
        System.out.println(JsonUtil.toJson(parse));
        List<AppQueryValidResourceData> resourceData = parseSourceXml(xml);
        System.out.println(JsonUtil.toJson(resourceData));
    }

测试结果:

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值