diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
index 91c6b8f2e..7f7494431 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/XmlUtils.java
@@ -3,7 +3,6 @@ package me.chanjar.weixin.common.util;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
-import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.error.WxRuntimeException;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
@@ -15,6 +14,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
+import java.util.stream.Collectors;
/**
*
@@ -50,8 +50,8 @@ public class XmlUtils {
private static Object element2MapOrString(Element element) {
- final List content = element.content();
- final Set names = names(content);
+ final List nodes = element.content();
+ final List names = names(nodes);
// 判断节点下有无非文本节点(非Text和CDATA),如无,直接取Text文本内容
if (names.size() < 1) {
@@ -59,10 +59,11 @@ public class XmlUtils {
}
Map result = Maps.newHashMap();
- if (names.size() == 1) {
+ Set distinctNames = Sets.newHashSet(names);
+ if (distinctNames.size() == 1) {
// 说明是个列表,各个子对象是相同的name
List list = Lists.newArrayList();
- for (Node node : content) {
+ for (Node node : nodes) {
if (node instanceof DefaultText) {
continue;
}
@@ -73,8 +74,8 @@ public class XmlUtils {
}
result.put(names.iterator().next(), list);
- } else {
- for (Node node : content) {
+ } else if (distinctNames.size() == names.size()) {
+ for (Node node : nodes) {
if (node instanceof DefaultText) {
continue;
}
@@ -83,13 +84,38 @@ public class XmlUtils {
result.put(node.getName(), element2MapOrString((Element) node));
}
}
+ } else {
+ // 说明有重复name,但不是全部都相同
+ Map 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 values;
+ if (result.containsKey(nodeName)) {
+ values = (List) result.get(nodeName);
+ } else {
+ values = Lists.newArrayList();
+ result.put(nodeName, values);
+ }
+
+ values.add(element2MapOrString((Element) node));
+ }
+ }
+ }
}
return result;
}
- private static Set names(List nodes) {
- Set names = Sets.newHashSet();
+ private static List names(List nodes) {
+ List names = Lists.newArrayList();
for (Node node : nodes) {
// 如果节点类型是Text或CDATA跳过
if (node instanceof DefaultText || node instanceof CDATA) {
diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/XmlUtilsTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/XmlUtilsTest.java
index 7b6bb536f..ff34475ef 100644
--- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/XmlUtilsTest.java
+++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/XmlUtilsTest.java
@@ -63,27 +63,54 @@ public class XmlUtilsTest {
assertThat(map).isNotNull();
final Map copyrightCheckResult = (Map) map.get("CopyrightCheckResult");
List> resultList = (List>) ((Map) copyrightCheckResult.get("ResultList")).get("item");
- assertThat(copyrightCheckResult).isNotNull();
- assertThat(copyrightCheckResult.get("Count")).isEqualTo("2");
- assertThat(copyrightCheckResult.get("CheckState")).isEqualTo("2");
+ assertThat(copyrightCheckResult)
+ .isNotNull()
+ .containsEntry("Count", "2")
+ .containsEntry("CheckState", "2");
- assertThat(resultList.get(0).get("ArticleIdx")).isEqualTo("1");
- assertThat(resultList.get(0).get("UserDeclareState")).isEqualTo("0");
- assertThat(resultList.get(0).get("AuditState")).isEqualTo("2");
- assertThat(resultList.get(0).get("OriginalArticleUrl")).isEqualTo("Url_1");
- assertThat(resultList.get(0).get("OriginalArticleType")).isEqualTo("1");
- assertThat(resultList.get(0).get("CanReprint")).isEqualTo("1");
- assertThat(resultList.get(0).get("NeedReplaceContent")).isEqualTo("1");
- assertThat(resultList.get(0).get("NeedShowReprintSource")).isEqualTo("1");
+ assertThat(resultList.get(0)).containsEntry("ArticleIdx", "1")
+ .containsEntry("UserDeclareState", "0")
+ .containsEntry("AuditState", "2")
+ .containsEntry("OriginalArticleUrl", "Url_1")
+ .containsEntry("OriginalArticleType", "1")
+ .containsEntry("CanReprint", "1")
+ .containsEntry("NeedReplaceContent", "1")
+ .containsEntry("NeedShowReprintSource", "1");
- assertThat(resultList.get(1).get("ArticleIdx")).isEqualTo("2");
- assertThat(resultList.get(1).get("UserDeclareState")).isEqualTo("0");
- assertThat(resultList.get(1).get("AuditState")).isEqualTo("2");
- assertThat(resultList.get(1).get("OriginalArticleUrl")).isEqualTo("Url_2");
- assertThat(resultList.get(1).get("OriginalArticleType")).isEqualTo("1");
- assertThat(resultList.get(1).get("CanReprint")).isEqualTo("1");
- assertThat(resultList.get(1).get("NeedReplaceContent")).isEqualTo("1");
- assertThat(resultList.get(1).get("NeedShowReprintSource")).isEqualTo("1");
+ assertThat(resultList.get(1)).containsEntry("ArticleIdx", "2")
+ .containsEntry("UserDeclareState", "0")
+ .containsEntry("AuditState", "2")
+ .containsEntry("OriginalArticleUrl", "Url_2")
+ .containsEntry("OriginalArticleType", "1")
+ .containsEntry("CanReprint", "1")
+ .containsEntry("NeedReplaceContent", "1")
+ .containsEntry("NeedShowReprintSource", "1");
+ }
+
+ @Test
+ public void testXml2Map_another() {
+ String xml = " 1481013459 2247503051 0 1 -
1 -
2 ";
+
+ final Map map = XmlUtils.xml2Map(xml);
+ assertThat(map).isNotNull()
+ .containsEntry("ToUserName", "gh_4d00ed8d6399")
+ .containsEntry("FromUserName", "oV5CrjpxgaGXNHIQigzNlgLTnwic")
+ .containsEntry("CreateTime", "1481013459")
+ .containsEntry("MsgType", "event");
+
+ Map publishEventInfo = (Map) map.get("PublishEventInfo");
+ assertThat(publishEventInfo).containsEntry("publish_id", "2247503051")
+ .containsEntry("publish_status", "0")
+ .containsEntry("article_id", "b5O2OUs25HBxRceL7hfReg-U9QGeq9zQjiDvy WP4Hq4");
+
+ Map articleDetail = (Map) publishEventInfo.get("article_detail");
+ assertThat(articleDetail).containsEntry("count", "1");
+ List< Map> item = (List>) 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");
}
}