Skip to content

Commit 1757aba

Browse files
committed
Add support U.fromXml(xml) for format.
1 parent 738d5a9 commit 1757aba

File tree

3 files changed

+64
-32
lines changed

3 files changed

+64
-32
lines changed

src/main/java/com/github/underscore/lodash/U.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1898,6 +1898,10 @@ public static Object fromXml(final String xml) {
18981898
return Xml.fromXml(xml);
18991899
}
19001900

1901+
public static Object fromXml(final String xml, final Xml.FromType fromType) {
1902+
return Xml.fromXml(xml, fromType);
1903+
}
1904+
19011905
public static Object fromXmlMakeArrays(final String xml) {
19021906
return Xml.fromXmlMakeArrays(xml);
19031907
}

src/main/java/com/github/underscore/lodash/Xml.java

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -951,11 +951,12 @@ public static String toXml(Map map) {
951951
}
952952

953953
@SuppressWarnings("unchecked")
954-
private static Object getValue(final Object value) {
954+
private static Object getValue(final Object value, final FromType fromType) {
955955
final Object localValue;
956956
if (value instanceof Map && ((Map<String, Object>) value).entrySet().size() == 1) {
957957
final Map.Entry<String, Object> entry = ((Map<String, Object>) value).entrySet().iterator().next();
958-
if (TEXT.equals(entry.getKey()) || entry.getKey().equals(ELEMENT_TEXT)) {
958+
if (TEXT.equals(entry.getKey())
959+
|| (fromType == FromType.FOR_CONVERT && ELEMENT_TEXT.equals(entry.getKey()))) {
959960
localValue = entry.getValue();
960961
} else {
961962
localValue = value;
@@ -988,7 +989,8 @@ private static Object stringToNumber(String number) {
988989
private static Object createMap(final org.w3c.dom.Node node,
989990
final BiFunction<Object, Set<String>, String> elementMapper,
990991
final Function<Object, Object> nodeMapper, final Map<String, Object> attrMap,
991-
final int[] uniqueIds, final String source, final int[] sourceIndex, final Set<String> namespaces) {
992+
final int[] uniqueIds, final String source, final int[] sourceIndex, final Set<String> namespaces,
993+
final FromType fromType) {
992994
final Map<String, Object> map = U.newLinkedHashMap();
993995
map.putAll(attrMap);
994996
final org.w3c.dom.NodeList nodeList = node.getChildNodes();
@@ -1004,7 +1006,7 @@ private static Object createMap(final org.w3c.dom.Node node,
10041006
if (currentNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
10051007
sourceIndex[0] = source.indexOf("<" + name, sourceIndex[0]) + name.length() + 1;
10061008
value = addElement(sourceIndex, source, elementMapper, nodeMapper,
1007-
uniqueIds, currentNode, namespaces);
1009+
uniqueIds, currentNode, namespaces, fromType);
10081010
} else {
10091011
if (COMMENT.equals(name)) {
10101012
sourceIndex[0] = source.indexOf("-->", sourceIndex[0]) + 3;
@@ -1018,7 +1020,7 @@ private static Object createMap(final org.w3c.dom.Node node,
10181020
|| currentNode.getNodeType() == org.w3c.dom.Node.DOCUMENT_TYPE_NODE) {
10191021
continue;
10201022
}
1021-
addNodeValue(map, name, value, elementMapper, nodeMapper, uniqueIds, namespaces);
1023+
addNodeValue(map, name, value, elementMapper, nodeMapper, uniqueIds, namespaces, fromType);
10221024
}
10231025
return checkNumberAndBoolean(map, node.getNodeName());
10241026
}
@@ -1052,8 +1054,8 @@ private static Object checkArray(final Map<String, Object> map, final String nam
10521054
final Map<String, Object> localMap4 = (Map) ((LinkedHashMap) localMap).clone();
10531055
localMap4.remove(ARRAY);
10541056
object = name.equals(XmlValue.getMapKey(localMap4))
1055-
? U.newArrayList(Arrays.asList(getValue(XmlValue.getMapValue(localMap4))))
1056-
: U.newArrayList(Arrays.asList(getValue(localMap4)));
1057+
? U.newArrayList(Arrays.asList(getValue(XmlValue.getMapValue(localMap4), FromType.FOR_CONVERT)))
1058+
: U.newArrayList(Arrays.asList(getValue(localMap4, FromType.FOR_CONVERT)));
10571059
} else {
10581060
object = localMap;
10591061
}
@@ -1102,7 +1104,8 @@ private static Map<String, Object> checkNullAndString(final Map<String, Object>
11021104
private static Object addElement(final int[] sourceIndex, final String source,
11031105
final BiFunction<Object, Set<String>, String> elementMapper,
11041106
final Function<Object, Object> nodeMapper, final int[] uniqueIds,
1105-
final org.w3c.dom.Node currentNode, final Set<String> namespaces) {
1107+
final org.w3c.dom.Node currentNode, final Set<String> namespaces,
1108+
final FromType fromType) {
11061109
final Map<String, Object> attrMapLocal = U.newLinkedHashMap();
11071110
if (currentNode.getAttributes().getLength() > 0) {
11081111
final java.util.regex.Matcher matcher = ATTRS.matcher(getAttributes(sourceIndex[0], source));
@@ -1114,7 +1117,7 @@ private static Object addElement(final int[] sourceIndex, final String source,
11141117
matcher.reset();
11151118
while (matcher.find()) {
11161119
addNodeValue(attrMapLocal, '-' + matcher.group(1), matcher.group(2),
1117-
elementMapper, nodeMapper, uniqueIds, namespaces);
1120+
elementMapper, nodeMapper, uniqueIds, namespaces, fromType);
11181121
}
11191122
}
11201123
if (getAttributes(sourceIndex[0], source).endsWith("/")
@@ -1124,7 +1127,7 @@ private static Object addElement(final int[] sourceIndex, final String source,
11241127
attrMapLocal.put(SELF_CLOSING, TRUE);
11251128
}
11261129
return createMap(currentNode, elementMapper, nodeMapper, attrMapLocal, uniqueIds, source,
1127-
sourceIndex, namespaces);
1130+
sourceIndex, namespaces, fromType);
11281131
}
11291132

11301133
static String getAttributes(final int sourceIndex, final String source) {
@@ -1197,39 +1200,39 @@ private static String unescapeName(final String name) {
11971200
@SuppressWarnings("unchecked")
11981201
private static void addNodeValue(final Map<String, Object> map, final String name, final Object value,
11991202
final BiFunction<Object, Set<String>, String> elementMapper, final Function<Object, Object> nodeMapper,
1200-
final int[] uniqueIds, final Set<String> namespaces) {
1203+
final int[] uniqueIds, final Set<String> namespaces, final FromType fromType) {
12011204
final String elementName = unescapeName(elementMapper.apply(name, namespaces));
12021205
if (map.containsKey(elementName)) {
12031206
if (TEXT.equals(elementName)) {
1204-
map.put(elementName + uniqueIds[0], nodeMapper.apply(getValue(value)));
1207+
map.put(elementName + uniqueIds[0], nodeMapper.apply(getValue(value, fromType)));
12051208
uniqueIds[0] += 1;
12061209
} else if (COMMENT.equals(elementName)) {
1207-
map.put(elementName + uniqueIds[1], nodeMapper.apply(getValue(value)));
1210+
map.put(elementName + uniqueIds[1], nodeMapper.apply(getValue(value, fromType)));
12081211
uniqueIds[1] += 1;
12091212
} else if (CDATA.equals(elementName)) {
1210-
map.put(elementName + uniqueIds[2], nodeMapper.apply(getValue(value)));
1213+
map.put(elementName + uniqueIds[2], nodeMapper.apply(getValue(value, fromType)));
12111214
uniqueIds[2] += 1;
12121215
} else {
12131216
final Object object = map.get(elementName);
12141217
if (object instanceof List) {
1215-
addText(map, elementName, (List<Object>) object, value);
1218+
addText(map, elementName, (List<Object>) object, value, fromType);
12161219
} else {
12171220
final List<Object> objects = U.newArrayList();
12181221
objects.add(object);
1219-
addText(map, elementName, objects, value);
1222+
addText(map, elementName, objects, value, fromType);
12201223
map.put(elementName, objects);
12211224
}
12221225
}
12231226
} else {
12241227
if (elementName != null) {
1225-
map.put(elementName, nodeMapper.apply(getValue(value)));
1228+
map.put(elementName, nodeMapper.apply(getValue(value, fromType)));
12261229
}
12271230
}
12281231
}
12291232

12301233
@SuppressWarnings("unchecked")
12311234
private static void addText(final Map<String, Object> map, final String name, final List<Object> objects,
1232-
final Object value) {
1235+
final Object value, final FromType fromType) {
12331236
int lastIndex = map.size() - 1;
12341237
final int index = objects.size();
12351238
while (true) {
@@ -1244,7 +1247,7 @@ private static void addText(final Map<String, Object> map, final String name, fi
12441247
objects.add(index, item);
12451248
lastIndex -= 1;
12461249
}
1247-
final Object newValue = getValue(value);
1250+
final Object newValue = getValue(value, fromType);
12481251
if (newValue instanceof List) {
12491252
objects.add(((List) newValue).get(0));
12501253
} else {
@@ -1254,6 +1257,16 @@ private static void addText(final Map<String, Object> map, final String name, fi
12541257

12551258
@SuppressWarnings("unchecked")
12561259
public static Object fromXml(final String xml) {
1260+
return fromXml(xml, FromType.FOR_CONVERT);
1261+
}
1262+
1263+
public enum FromType {
1264+
FOR_CONVERT,
1265+
FOR_FORMAT
1266+
}
1267+
1268+
@SuppressWarnings("unchecked")
1269+
public static Object fromXml(final String xml, final FromType fromType) {
12571270
if (xml == null) {
12581271
return null;
12591272
}
@@ -1268,8 +1281,8 @@ public Object apply(Object object) {
12681281
return object;
12691282
}
12701283
}, Collections.<String, Object>emptyMap(), new int[] {1, 1, 1}, xml, new int[] {0},
1271-
U.<String>newLinkedHashSet());
1272-
if (checkResult(xml, document, result)) {
1284+
U.<String>newLinkedHashSet(), fromType);
1285+
if (checkResult(xml, document, result, fromType)) {
12731286
return ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue();
12741287
}
12751288
return result;
@@ -1279,7 +1292,8 @@ public Object apply(Object object) {
12791292
}
12801293

12811294
@SuppressWarnings("unchecked")
1282-
private static boolean checkResult(final String xml, org.w3c.dom.Document document, final Object result) {
1295+
private static boolean checkResult(final String xml, org.w3c.dom.Document document, final Object result,
1296+
final FromType fromType) {
12831297
final Map<String, String> headerAttributes = getHeaderAttributes(xml);
12841298
if (document.getXmlEncoding() != null && !"UTF-8".equalsIgnoreCase(document.getXmlEncoding())) {
12851299
((Map) result).put(ENCODING, document.getXmlEncoding());
@@ -1288,7 +1302,8 @@ private static boolean checkResult(final String xml, org.w3c.dom.Document docume
12881302
}
12891303
} else if (headerAttributes.containsKey(STANDALONE.substring(1))) {
12901304
((Map) result).put(STANDALONE, headerAttributes.get(STANDALONE.substring(1)));
1291-
} else if (((Map.Entry) ((Map) result).entrySet().iterator().next()).getKey().equals("root")
1305+
} else if (fromType == FromType.FOR_CONVERT
1306+
&& ((Map.Entry) ((Map) result).entrySet().iterator().next()).getKey().equals("root")
12921307
&& (((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue() instanceof List
12931308
|| ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue() instanceof Map)) {
12941309
if (xml.startsWith(XML_HEADER)) {
@@ -1345,8 +1360,8 @@ public Object apply(Object object) {
13451360
return object instanceof List ? object : U.newArrayList(Arrays.asList(object));
13461361
}
13471362
}, Collections.<String, Object>emptyMap(), new int[] {1, 1, 1}, xml, new int[] {0},
1348-
U.<String>newLinkedHashSet());
1349-
if (checkResult(xml, document, result)) {
1363+
U.<String>newLinkedHashSet(), FromType.FOR_CONVERT);
1364+
if (checkResult(xml, document, result, FromType.FOR_CONVERT)) {
13501365
return ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue();
13511366
}
13521367
return result;
@@ -1364,8 +1379,8 @@ public Object apply(Object object) {
13641379
return object;
13651380
}
13661381
}, Collections.<String, Object>emptyMap(), new int[]{1, 1, 1}, xml, new int[]{0},
1367-
U.<String>newLinkedHashSet());
1368-
if (checkResult(xml, document, result)) {
1382+
U.<String>newLinkedHashSet(), FromType.FOR_CONVERT);
1383+
if (checkResult(xml, document, result, FromType.FOR_CONVERT)) {
13691384
return ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue();
13701385
}
13711386
return result;
@@ -1421,11 +1436,8 @@ public String apply(Object object, Set<String> namespaces) {
14211436

14221437
@SuppressWarnings("unchecked")
14231438
public static String formatXml(String xml, XmlStringBuilder.Step identStep) {
1424-
Object result = fromXml(xml);
1425-
if (result instanceof Map) {
1426-
return toXml((Map) result, identStep);
1427-
}
1428-
return toXml((List) result, identStep);
1439+
Object result = fromXml(xml, FromType.FOR_FORMAT);
1440+
return toXml((Map) result, identStep);
14291441
}
14301442

14311443
public static String formatXml(String xml) {

src/test/java/com/github/underscore/lodash/StringTest.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,6 +2195,22 @@ public void toJsonFromXml26() {
21952195
assertNull(U.get(map, "a.d"));
21962196
}
21972197

2198+
@SuppressWarnings("unchecked")
2199+
@Test
2200+
public void toJsonFromXml27() {
2201+
final String xml = "<root>\n <element/>\n</root>";
2202+
final String json = "{\n"
2203+
+ " \"root\": {\n"
2204+
+ " \"element\": {\n"
2205+
+ " \"-self-closing\": \"true\"\n"
2206+
+ " }\n"
2207+
+ " },\n"
2208+
+ " \"#omit-xml-declaration\": \"yes\"\n"
2209+
+ "}";
2210+
assertEquals(json, U.toJson((Map<String, Object>) U.fromXml(xml, Xml.FromType.FOR_FORMAT)));
2211+
assertEquals(xml, U.toXml((Map<String, Object>) U.fromJson(json)));
2212+
}
2213+
21982214
@SuppressWarnings("unchecked")
21992215
@Test
22002216
public void toXmlFromJson() {

0 commit comments

Comments
 (0)