开始之前我们先来看一下这个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));
}
测试结果: