diff --git a/src/main/java/com/github/underscore/lodash/U.java b/src/main/java/com/github/underscore/lodash/U.java index 0e59931c..5bc2e5fe 100644 --- a/src/main/java/com/github/underscore/lodash/U.java +++ b/src/main/java/com/github/underscore/lodash/U.java @@ -1745,6 +1745,8 @@ public static String toJson(Map map) { public static class XmlStringBuilder { protected final StringBuilder builder; private int ident; + private int saveAttrPosition; + private int saveTextPosition; public XmlStringBuilder() { builder = new StringBuilder("\n\n"); @@ -1757,10 +1759,32 @@ public XmlStringBuilder(StringBuilder builder, int ident) { } public XmlStringBuilder append(final String string) { + if (">".equals(string)) { + saveAttrPosition = builder.length(); + saveTextPosition = builder.length() + 1; + } builder.append(string); return this; } + public XmlStringBuilder insert(final String key, final String value) { + builder.insert(saveAttrPosition, " " + key + "=\""); + saveAttrPosition += (" " + key + "=\"").length(); + saveTextPosition += (" " + key + "=\"").length(); + builder.insert(saveAttrPosition, value + "\""); + saveAttrPosition += (value + "\"").length(); + saveTextPosition += (value + "\"").length(); + return this; + } + + public XmlStringBuilder insert(final String value) { + builder.delete(saveTextPosition, saveTextPosition + 1); + builder.insert(saveTextPosition, value); + saveTextPosition += value.length(); + saveAttrPosition += value.length(); + return this; + } + public XmlStringBuilder fillSpaces() { for (int index = 0; index < ident; index += 1) { builder.append(' '); @@ -1985,13 +2009,26 @@ public static void writeXml(Map map, XmlStringBuilder builder) { } Iterator iter = map.entrySet().iterator(); + boolean textWasInserted = false; while (iter.hasNext()) { Map.Entry entry = (Map.Entry) iter.next(); - builder.fillSpaces().append("<").append(escape(String.valueOf(entry.getKey()))).append(">"); - XmlValue.writeXml(entry.getValue(), builder); - builder.append(""); - if (iter.hasNext()) { - builder.newLine(); + if (escape(String.valueOf(entry.getKey())).startsWith("-") && entry.getValue() instanceof String) { + builder.insert(escape(String.valueOf(entry.getKey())).substring(1), escape((String) entry.getValue())); + } else if ("#text".equals(escape(String.valueOf(entry.getKey())))) { + builder.insert(escape((String) entry.getValue())); + textWasInserted = true; + } else { + if (textWasInserted) { + textWasInserted = false; + } else { + builder.fillSpaces(); + } + builder.append("<").append(escape(String.valueOf(entry.getKey()))).append(">"); + XmlValue.writeXml(entry.getValue(), builder); + builder.append(""); + if (iter.hasNext()) { + builder.newLine(); + } } } } diff --git a/src/test/java/com/github/underscore/lodash/StringTest.java b/src/test/java/com/github/underscore/lodash/StringTest.java index e004e711..5de7f9b5 100644 --- a/src/test/java/com/github/underscore/lodash/StringTest.java +++ b/src/test/java/com/github/underscore/lodash/StringTest.java @@ -1371,6 +1371,53 @@ public void toXmlFromJson() { U.toXml((Map) U.fromJson(json))); } + @SuppressWarnings("unchecked") + @Test + public void toXmlFromJson2() { + final String json = "{\n" + + " \"widget\": {\n" + + " \"debug\": \"on\",\n" + + " \"window\": {\n" + + " \"-title\": \"Sample Konfabulator Widget\",\n" + + " \"#text\": \"\\n I just put some text here\\n \",\n" + + " \"name\": \"main_window\",\n" + + " \"width\": \"500\",\n" + + " \"height\": \"500\"\n" + + " },\n" + + " \"image\": {\n" + + " \"-name\": \"sun1\",\n" + + " \"-src\": \"Images\\/Sun.png\",\n" + + " \"-test\": [],\n" + + " \"hOffset\": {\n" + + " \"#text\": \"250\",\n" + + " \"unit\": \"mm\"\n" + + " },\n" + + " \"vOffset\": \"250\",\n" + + " \"alignment\": \"center\"\n" + + " }\n" + + " }\n" + + "}"; + assertEquals("\n" + + "\n" + + " on\n" + + " \n" + + " I just put some text here\n" + + " main_window\n" + + " 500\n" + + " 500\n" + + " \n" + + " \n" + + " <-test>\n\n" + + " \n" + + " 250mm\n" + + " \n" + + " 250\n" + + " center\n" + + " \n" + + "", + U.toXml((Map) U.fromJson(json))); + } + @SuppressWarnings("unchecked") @Test public void toXml() {