mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-11-01 00:46:54 +08:00 
			
		
		
		
	🎨 XmlUtils工具类优化,支持变态微信消息
This commit is contained in:
		| @@ -3,7 +3,6 @@ package me.chanjar.weixin.common.util; | |||||||
| import com.google.common.collect.Lists; | import com.google.common.collect.Lists; | ||||||
| import com.google.common.collect.Maps; | import com.google.common.collect.Maps; | ||||||
| import com.google.common.collect.Sets; | import com.google.common.collect.Sets; | ||||||
| import me.chanjar.weixin.common.error.WxErrorException; |  | ||||||
| import me.chanjar.weixin.common.error.WxRuntimeException; | import me.chanjar.weixin.common.error.WxRuntimeException; | ||||||
| import org.dom4j.*; | import org.dom4j.*; | ||||||
| import org.dom4j.io.SAXReader; | import org.dom4j.io.SAXReader; | ||||||
| @@ -15,6 +14,7 @@ import java.util.HashMap; | |||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * <pre> |  * <pre> | ||||||
| @@ -50,8 +50,8 @@ public class XmlUtils { | |||||||
|  |  | ||||||
|   private static Object element2MapOrString(Element element) { |   private static Object element2MapOrString(Element element) { | ||||||
|  |  | ||||||
|     final List<Node> content = element.content(); |     final List<Node> nodes = element.content(); | ||||||
|     final Set<String> names = names(content); |     final List<String> names = names(nodes); | ||||||
|  |  | ||||||
|     // 判断节点下有无非文本节点(非Text和CDATA),如无,直接取Text文本内容 |     // 判断节点下有无非文本节点(非Text和CDATA),如无,直接取Text文本内容 | ||||||
|     if (names.size() < 1) { |     if (names.size() < 1) { | ||||||
| @@ -59,10 +59,11 @@ public class XmlUtils { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     Map<String, Object> result = Maps.newHashMap(); |     Map<String, Object> result = Maps.newHashMap(); | ||||||
|     if (names.size() == 1) { |     Set<String> distinctNames = Sets.newHashSet(names); | ||||||
|  |     if (distinctNames.size() == 1) { | ||||||
|       // 说明是个列表,各个子对象是相同的name |       // 说明是个列表,各个子对象是相同的name | ||||||
|       List<Object> list = Lists.newArrayList(); |       List<Object> list = Lists.newArrayList(); | ||||||
|       for (Node node : content) { |       for (Node node : nodes) { | ||||||
|         if (node instanceof DefaultText) { |         if (node instanceof DefaultText) { | ||||||
|           continue; |           continue; | ||||||
|         } |         } | ||||||
| @@ -73,8 +74,8 @@ public class XmlUtils { | |||||||
|       } |       } | ||||||
|  |  | ||||||
|       result.put(names.iterator().next(), list); |       result.put(names.iterator().next(), list); | ||||||
|     } else { |     } else if (distinctNames.size() == names.size()) { | ||||||
|       for (Node node : content) { |       for (Node node : nodes) { | ||||||
|         if (node instanceof DefaultText) { |         if (node instanceof DefaultText) { | ||||||
|           continue; |           continue; | ||||||
|         } |         } | ||||||
| @@ -83,13 +84,38 @@ public class XmlUtils { | |||||||
|           result.put(node.getName(), element2MapOrString((Element) node)); |           result.put(node.getName(), element2MapOrString((Element) node)); | ||||||
|         } |         } | ||||||
|       } |       } | ||||||
|  |     } else { | ||||||
|  |       // 说明有重复name,但不是全部都相同 | ||||||
|  |       Map<String, Long> namesCountMap = names.stream().collect(Collectors.groupingBy(a -> a, Collectors.counting())); | ||||||
|  |       for (Node node : nodes) { | ||||||
|  |         if (node instanceof DefaultText) { | ||||||
|  |           continue; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (node instanceof Element) { | ||||||
|  |           String nodeName = node.getName(); | ||||||
|  |           if (namesCountMap.get(nodeName) == 1) { | ||||||
|  |             result.put(nodeName, element2MapOrString((Element) node)); | ||||||
|  |           } else { | ||||||
|  |             List<Object> values; | ||||||
|  |             if (result.containsKey(nodeName)) { | ||||||
|  |               values = (List<Object>) result.get(nodeName); | ||||||
|  |             } else { | ||||||
|  |               values = Lists.newArrayList(); | ||||||
|  |               result.put(nodeName, values); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             values.add(element2MapOrString((Element) node)); | ||||||
|  |           } | ||||||
|  |         } | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     return result; |     return result; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private static Set<String> names(List<Node> nodes) { |   private static List<String> names(List<Node> nodes) { | ||||||
|     Set<String> names = Sets.newHashSet(); |     List<String> names = Lists.newArrayList(); | ||||||
|     for (Node node : nodes) { |     for (Node node : nodes) { | ||||||
|       // 如果节点类型是Text或CDATA跳过 |       // 如果节点类型是Text或CDATA跳过 | ||||||
|       if (node instanceof DefaultText || node instanceof CDATA) { |       if (node instanceof DefaultText || node instanceof CDATA) { | ||||||
|   | |||||||
| @@ -63,27 +63,54 @@ public class XmlUtilsTest { | |||||||
|     assertThat(map).isNotNull(); |     assertThat(map).isNotNull(); | ||||||
|     final Map<String, Object> copyrightCheckResult = (Map<String, Object>) map.get("CopyrightCheckResult"); |     final Map<String, Object> copyrightCheckResult = (Map<String, Object>) map.get("CopyrightCheckResult"); | ||||||
|     List<Map<String, Object>> resultList = (List<Map<String, Object>>) ((Map<String, Object>) copyrightCheckResult.get("ResultList")).get("item"); |     List<Map<String, Object>> resultList = (List<Map<String, Object>>) ((Map<String, Object>) copyrightCheckResult.get("ResultList")).get("item"); | ||||||
|     assertThat(copyrightCheckResult).isNotNull(); |  | ||||||
|  |  | ||||||
|     assertThat(copyrightCheckResult.get("Count")).isEqualTo("2"); |     assertThat(copyrightCheckResult) | ||||||
|     assertThat(copyrightCheckResult.get("CheckState")).isEqualTo("2"); |       .isNotNull() | ||||||
|  |       .containsEntry("Count", "2") | ||||||
|  |       .containsEntry("CheckState", "2"); | ||||||
|  |  | ||||||
|     assertThat(resultList.get(0).get("ArticleIdx")).isEqualTo("1"); |     assertThat(resultList.get(0)).containsEntry("ArticleIdx", "1") | ||||||
|     assertThat(resultList.get(0).get("UserDeclareState")).isEqualTo("0"); |       .containsEntry("UserDeclareState", "0") | ||||||
|     assertThat(resultList.get(0).get("AuditState")).isEqualTo("2"); |       .containsEntry("AuditState", "2") | ||||||
|     assertThat(resultList.get(0).get("OriginalArticleUrl")).isEqualTo("Url_1"); |       .containsEntry("OriginalArticleUrl", "Url_1") | ||||||
|     assertThat(resultList.get(0).get("OriginalArticleType")).isEqualTo("1"); |       .containsEntry("OriginalArticleType", "1") | ||||||
|     assertThat(resultList.get(0).get("CanReprint")).isEqualTo("1"); |       .containsEntry("CanReprint", "1") | ||||||
|     assertThat(resultList.get(0).get("NeedReplaceContent")).isEqualTo("1"); |       .containsEntry("NeedReplaceContent", "1") | ||||||
|     assertThat(resultList.get(0).get("NeedShowReprintSource")).isEqualTo("1"); |       .containsEntry("NeedShowReprintSource", "1"); | ||||||
|  |  | ||||||
|     assertThat(resultList.get(1).get("ArticleIdx")).isEqualTo("2"); |     assertThat(resultList.get(1)).containsEntry("ArticleIdx", "2") | ||||||
|     assertThat(resultList.get(1).get("UserDeclareState")).isEqualTo("0"); |       .containsEntry("UserDeclareState", "0") | ||||||
|     assertThat(resultList.get(1).get("AuditState")).isEqualTo("2"); |       .containsEntry("AuditState", "2") | ||||||
|     assertThat(resultList.get(1).get("OriginalArticleUrl")).isEqualTo("Url_2"); |       .containsEntry("OriginalArticleUrl", "Url_2") | ||||||
|     assertThat(resultList.get(1).get("OriginalArticleType")).isEqualTo("1"); |       .containsEntry("OriginalArticleType", "1") | ||||||
|     assertThat(resultList.get(1).get("CanReprint")).isEqualTo("1"); |       .containsEntry("CanReprint", "1") | ||||||
|     assertThat(resultList.get(1).get("NeedReplaceContent")).isEqualTo("1"); |       .containsEntry("NeedReplaceContent", "1") | ||||||
|     assertThat(resultList.get(1).get("NeedShowReprintSource")).isEqualTo("1"); |       .containsEntry("NeedShowReprintSource", "1"); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @Test | ||||||
|  |   public void testXml2Map_another() { | ||||||
|  |     String xml = "<xml> <ToUserName><![CDATA[gh_4d00ed8d6399]]></ToUserName> <FromUserName><![CDATA[oV5CrjpxgaGXNHIQigzNlgLTnwic]]></FromUserName> <CreateTime>1481013459</CreateTime> <MsgType><![CDATA[event]]></MsgType> <Event><![CDATA[PUBLISHJOBFINISH]]></Event> <PublishEventInfo> <publish_id>2247503051</publish_id> <publish_status>0</publish_status> <article_id><![CDATA[b5O2OUs25HBxRceL7hfReg-U9QGeq9zQjiDvy WP4Hq4]]></article_id> <article_detail> <count>1</count> <item> <idx>1</idx> <article_url><![CDATA[ARTICLE_URL]]></article_url> </item> <item> <idx>2</idx> <article_url><![CDATA[ARTICLE_URL_2]]></article_url> </item> </article_detail> </PublishEventInfo> </xml>"; | ||||||
|  |  | ||||||
|  |     final Map<String, Object> map = XmlUtils.xml2Map(xml); | ||||||
|  |     assertThat(map).isNotNull() | ||||||
|  |       .containsEntry("ToUserName", "gh_4d00ed8d6399") | ||||||
|  |       .containsEntry("FromUserName", "oV5CrjpxgaGXNHIQigzNlgLTnwic") | ||||||
|  |       .containsEntry("CreateTime", "1481013459") | ||||||
|  |       .containsEntry("MsgType", "event"); | ||||||
|  |  | ||||||
|  |     Map<String, Object> publishEventInfo = (Map<String, Object>) map.get("PublishEventInfo"); | ||||||
|  |     assertThat(publishEventInfo).containsEntry("publish_id", "2247503051") | ||||||
|  |       .containsEntry("publish_status", "0") | ||||||
|  |       .containsEntry("article_id", "b5O2OUs25HBxRceL7hfReg-U9QGeq9zQjiDvy WP4Hq4"); | ||||||
|  |  | ||||||
|  |     Map<String, Object> articleDetail = (Map<String, Object>) publishEventInfo.get("article_detail"); | ||||||
|  |     assertThat(articleDetail).containsEntry("count", "1"); | ||||||
|  |     List< Map<String, Object>> item = (List<Map<String, Object>>) articleDetail.get("item"); | ||||||
|  |     assertThat(item.get(0)).containsEntry("idx", "1") | ||||||
|  |       .containsEntry("article_url", "ARTICLE_URL"); | ||||||
|  |  | ||||||
|  |     assertThat(item.get(1)).containsEntry("idx", "2") | ||||||
|  |       .containsEntry("article_url", "ARTICLE_URL_2"); | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Binary Wang
					Binary Wang