Skip to content

Commit 0ed2386

Browse files
authored
Add attributes support for U.fromXml(string).
1 parent 5bd119d commit 0ed2386

File tree

3 files changed

+81
-19
lines changed

3 files changed

+81
-19
lines changed

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

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2537,7 +2537,7 @@ public Object fromJson() {
25372537

25382538
@SuppressWarnings("unchecked")
25392539
private static Object getValue(final Object value) {
2540-
if (value instanceof Map && ((Map<String, Object>) value).entrySet().iterator().hasNext()) {
2540+
if (value instanceof Map && ((Map<String, Object>) value).entrySet().size() == 1) {
25412541
final Map.Entry<String, Object> entry = ((Map<String, Object>) value).entrySet().iterator().next();
25422542
if (entry.getKey().equals("#text") || entry.getKey().equals("element")) {
25432543
return entry.getValue();
@@ -2548,36 +2548,51 @@ private static Object getValue(final Object value) {
25482548

25492549
@SuppressWarnings("unchecked")
25502550
private static Map<String, Object> createMap(final org.w3c.dom.Node node,
2551-
final Function<Object, Object> nodeMapper) {
2551+
final Function<Object, Object> nodeMapper, Map<String, Object> attrMap) {
25522552
final Map<String, Object> map = newLinkedHashMap();
2553+
map.putAll(attrMap);
25532554
final org.w3c.dom.NodeList nodeList = node.getChildNodes();
25542555
for (int index = 0; index < nodeList.getLength(); index++) {
25552556
final org.w3c.dom.Node currentNode = nodeList.item(index);
25562557
final String name = currentNode.getNodeName();
25572558
final Object value;
2559+
final int attributesLength = currentNode.getAttributes() == null
2560+
? 0 : currentNode.getAttributes().getLength();
25582561
if (currentNode.getNodeType() == org.w3c.dom.Node.ELEMENT_NODE) {
2559-
value = createMap(currentNode, nodeMapper);
2562+
final Map<String, Object> attrMapLocal = newLinkedHashMap();
2563+
for (int indexAttr = 0; indexAttr < attributesLength; indexAttr += 1) {
2564+
final org.w3c.dom.Node currentNodeAttr = currentNode.getAttributes().item(indexAttr);
2565+
addNodeValue(attrMapLocal, '-' + currentNodeAttr.getNodeName(),
2566+
currentNodeAttr.getTextContent(), nodeMapper);
2567+
}
2568+
value = createMap(currentNode, nodeMapper, attrMapLocal);
25602569
} else {
25612570
value = currentNode.getTextContent();
25622571
}
25632572
if ("#text".equals(name) && value.toString().trim().isEmpty()) {
25642573
continue;
25652574
}
2566-
if (map.containsKey(name)) {
2567-
final Object object = map.get(name);
2568-
if (object instanceof List) {
2569-
((List<Object>) object).add(getValue(value));
2570-
} else {
2571-
final List<Object> objects = newArrayList();
2572-
objects.add(object);
2573-
objects.add(getValue(value));
2574-
map.put(name, objects);
2575-
}
2575+
addNodeValue(map, name, value, nodeMapper);
2576+
}
2577+
return map;
2578+
}
2579+
2580+
@SuppressWarnings("unchecked")
2581+
private static void addNodeValue(final Map<String, Object> map, final String name, final Object value,
2582+
final Function<Object, Object> nodeMapper) {
2583+
if (map.containsKey(name)) {
2584+
final Object object = map.get(name);
2585+
if (object instanceof List) {
2586+
((List<Object>) object).add(getValue(value));
25762587
} else {
2577-
map.put(name, nodeMapper.apply(getValue(value)));
2588+
final List<Object> objects = newArrayList();
2589+
objects.add(object);
2590+
objects.add(getValue(value));
2591+
map.put(name, objects);
25782592
}
2593+
} else {
2594+
map.put(name, nodeMapper.apply(getValue(value)));
25792595
}
2580-
return map;
25812596
}
25822597

25832598
public static Object fromXml(final String xml) {
@@ -2591,7 +2606,7 @@ public static Object fromXml(final String xml) {
25912606
public Object apply(Object object) {
25922607
return object;
25932608
}
2594-
});
2609+
}, Collections.<String, Object>emptyMap());
25952610
} catch (Exception ex) {
25962611
throw new IllegalArgumentException(ex);
25972612
}
@@ -2608,7 +2623,7 @@ public static Object fromXmlMakeArrays(final String xml) {
26082623
public Object apply(Object object) {
26092624
return object instanceof List ? object : newArrayList(Arrays.asList(object));
26102625
}
2611-
});
2626+
}, Collections.<String, Object>emptyMap());
26122627
} catch (Exception ex) {
26132628
throw new IllegalArgumentException(ex);
26142629
}

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

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -800,8 +800,13 @@ public void stackoverflow4() {
800800
+ " <Gelco type=\"int\">26</Gelco>"
801801
+ "</root>";
802802

803-
assertEquals("{root={Durapipe=1, EXPLAIN=2, woods=2, hanging=3, hastily=2, localized=1, "
804-
+ "Schuster=5, regularize=1, LASR=1, LAST=22, Gelch=2, Gelco=26}}", U.fromXml(xml).toString());
803+
assertEquals("{root={Durapipe={-type=int, #text=1}, EXPLAIN={-type=int, #text=2}, "
804+
+ "woods={-type=int, #text=2}, hanging={-type=int, #text=3}, "
805+
+ "hastily={-type=int, #text=2}, localized={-type=int, #text=1}, "
806+
+ "Schuster={-type=int, #text=5}, regularize={-type=int, #text=1}, "
807+
+ "LASR={-type=int, #text=1}, LAST={-type=int, #text=22}, "
808+
+ "Gelch={-type=int, #text=2}, Gelco={-type=int, #text=26}}}",
809+
U.fromXml(xml).toString());
805810
}
806811

807812
@SuppressWarnings("unchecked")

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

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1315,6 +1315,48 @@ public void toJsonFromXml() {
13151315
U.toJson((Map<String, Object>) U.fromXml(xml)));
13161316
}
13171317

1318+
@SuppressWarnings("unchecked")
1319+
@Test
1320+
public void toJsonFromXml2() {
1321+
final String xml = "<widget>\n"
1322+
+ " <debug>on</debug>\n"
1323+
+ " <window title=\"Sample Konfabulator Widget\">\n"
1324+
+ " I just put some text here\n"
1325+
+ " <name>main_window</name>\n"
1326+
+ " <width>500</width>\n"
1327+
+ " <height>500</height>\n"
1328+
+ " </window>\n"
1329+
+ " <image src=\"Images/Sun.png\" name=\"sun1\">\n"
1330+
+ " <hOffset>250<unit>mm</unit></hOffset>\n"
1331+
+ " <vOffset>250</vOffset>\n"
1332+
+ " <alignment>center</alignment>\n"
1333+
+ " </image>\n"
1334+
+ "</widget>";
1335+
assertEquals("{\n"
1336+
+ " \"widget\": {\n"
1337+
+ " \"debug\": \"on\",\n"
1338+
+ " \"window\": {\n"
1339+
+ " \"-title\": \"Sample Konfabulator Widget\",\n"
1340+
+ " \"#text\": \"\\n I just put some text here\\n \",\n"
1341+
+ " \"name\": \"main_window\",\n"
1342+
+ " \"width\": \"500\",\n"
1343+
+ " \"height\": \"500\"\n"
1344+
+ " },\n"
1345+
+ " \"image\": {\n"
1346+
+ " \"-name\": \"sun1\",\n"
1347+
+ " \"-src\": \"Images\\/Sun.png\",\n"
1348+
+ " \"hOffset\": {\n"
1349+
+ " \"#text\": \"250\",\n"
1350+
+ " \"unit\": \"mm\"\n"
1351+
+ " },\n"
1352+
+ " \"vOffset\": \"250\",\n"
1353+
+ " \"alignment\": \"center\"\n"
1354+
+ " }\n"
1355+
+ " }\n"
1356+
+ "}",
1357+
U.toJson((Map<String, Object>) U.fromXml(xml)));
1358+
}
1359+
13181360
@SuppressWarnings("unchecked")
13191361
@Test
13201362
public void toXmlFromJson() {

0 commit comments

Comments
 (0)