Skip to content

Commit 505d0b5

Browse files
authored
Add encoding support.
1 parent 1ae434e commit 505d0b5

File tree

2 files changed

+57
-14
lines changed

2 files changed

+57
-14
lines changed

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

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public final class Xml {
3131
private static final String ELEMENT_TEXT = "element";
3232
private static final String CDATA = "#cdata-section";
3333
private static final String COMMENT = "#comment";
34+
private static final String ENCODING = "#encoding";
3435
private static final String TEXT = "#text";
3536
private static final String ELEMENT = "<" + ELEMENT_TEXT + ">";
3637
private static final String CLOSED_ELEMENT = "</" + ELEMENT_TEXT + ">";
@@ -109,8 +110,9 @@ public String toString() {
109110
}
110111

111112
public static class XmlStringBuilderWithoutRoot extends XmlStringBuilder {
112-
public XmlStringBuilderWithoutRoot(XmlStringBuilder.Step identStep) {
113-
super(new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"), identStep, 0);
113+
public XmlStringBuilderWithoutRoot(XmlStringBuilder.Step identStep, String encoding) {
114+
super(new StringBuilder("<?xml version=\"1.0\" encoding=\""
115+
+ U.escape(encoding) + "\"?>\n"), identStep, 0);
114116
}
115117

116118
public String toString() {
@@ -659,7 +661,7 @@ private static void escape(String s, StringBuilder sb) {
659661
}
660662

661663
public static String toXml(Collection collection, XmlStringBuilder.Step identStep) {
662-
final XmlStringBuilder builder = new XmlStringBuilderWithoutRoot(identStep);
664+
final XmlStringBuilder builder = new XmlStringBuilderWithoutRoot(identStep, UTF_8.name());
663665
builder.append("<root>").incIdent();
664666
if (collection == null || !collection.isEmpty()) {
665667
builder.newLine();
@@ -673,13 +675,22 @@ public static String toXml(Collection collection) {
673675
}
674676

675677
public static String toXml(Map map, XmlStringBuilder.Step identStep) {
676-
final XmlStringBuilder builder = new XmlStringBuilderWithoutRoot(identStep);
677-
if (map == null || map.size() != 1
678-
|| ((String) ((Map.Entry) map.entrySet().iterator().next()).getKey()).startsWith("-")
679-
|| ((Map.Entry) map.entrySet().iterator().next()).getValue() instanceof List) {
680-
XmlObject.writeXml(map, "root", builder, false, U.<String>newLinkedHashSet());
678+
final XmlStringBuilder builder;
679+
final Map localMap;
680+
if (map != null && map.containsKey(ENCODING)) {
681+
builder = new XmlStringBuilderWithoutRoot(identStep, String.valueOf(map.get(ENCODING)));
682+
localMap = (Map) U.clone(map);
683+
localMap.remove(ENCODING);
681684
} else {
682-
XmlObject.writeXml(map, null, builder, false, U.<String>newLinkedHashSet());
685+
builder = new XmlStringBuilderWithoutRoot(identStep, UTF_8.name());
686+
localMap = map;
687+
}
688+
if (localMap == null || localMap.size() != 1
689+
|| ((String) ((Map.Entry) localMap.entrySet().iterator().next()).getKey()).startsWith("-")
690+
|| ((Map.Entry) localMap.entrySet().iterator().next()).getValue() instanceof List) {
691+
XmlObject.writeXml(localMap, "root", builder, false, U.<String>newLinkedHashSet());
692+
} else {
693+
XmlObject.writeXml(localMap, null, builder, false, U.<String>newLinkedHashSet());
683694
}
684695
return builder.toString();
685696
}
@@ -795,7 +806,9 @@ public Object apply(Object object) {
795806
return object;
796807
}
797808
}, Collections.<String, Object>emptyMap(), new int[] {1, 1, 1}, valueMapper);
798-
if (((Map.Entry) ((Map) result).entrySet().iterator().next()).getKey().equals("root")
809+
if (document.getXmlEncoding() != null && !"UTF-8".equalsIgnoreCase(document.getXmlEncoding())) {
810+
((Map) result).put(ENCODING, document.getXmlEncoding());
811+
} else if (((Map.Entry) ((Map) result).entrySet().iterator().next()).getKey().equals("root")
799812
&& (((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue() instanceof List
800813
|| ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue() instanceof Map)) {
801814
return ((Map.Entry) ((Map) result).entrySet().iterator().next()).getValue();
@@ -814,16 +827,15 @@ public Object apply(Object object) {
814827
});
815828
}
816829

817-
private static org.w3c.dom.Document createDocument(final String xml) throws java.io.IOException,
818-
javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException {
819-
final java.io.InputStream stream = new java.io.ByteArrayInputStream(xml.getBytes(UTF_8));
830+
private static org.w3c.dom.Document createDocument(final String xml)
831+
throws java.io.IOException, javax.xml.parsers.ParserConfigurationException, org.xml.sax.SAXException {
820832
final javax.xml.parsers.DocumentBuilderFactory factory =
821833
javax.xml.parsers.DocumentBuilderFactory.newInstance();
822834
factory.setNamespaceAware(true);
823835
factory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING, true);
824836
final javax.xml.parsers.DocumentBuilder builder = factory.newDocumentBuilder();
825837
builder.setErrorHandler(new org.xml.sax.helpers.DefaultHandler());
826-
return builder.parse(stream);
838+
return builder.parse(new org.xml.sax.InputSource(new java.io.StringReader(xml)));
827839
}
828840

829841
public static Object fromXmlMakeArrays(final String xml) {

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1561,6 +1561,18 @@ public void toJsonFromXml11() {
15611561
U.toJson((Map<String, Object>) U.fromXml(xml3)));
15621562
}
15631563

1564+
@SuppressWarnings("unchecked")
1565+
@Test
1566+
public void toJsonFromXml12() {
1567+
final String xml = "<?xml version=\"1.0\" encoding=\"windows-1251\"?><a></a>";
1568+
assertEquals("{\n"
1569+
+ " \"a\": {\n"
1570+
+ " },\n"
1571+
+ " \"#encoding\": \"windows-1251\"\n"
1572+
+ "}",
1573+
U.toJson((Map<String, Object>) U.fromXml(xml)));
1574+
}
1575+
15641576
@SuppressWarnings("unchecked")
15651577
@Test
15661578
public void toXmlFromJson() {
@@ -1910,6 +1922,25 @@ public void toXmlFromJson18() {
19101922
U.toXml((Map<String, Object>) U.fromJson(json)));
19111923
}
19121924

1925+
@SuppressWarnings("unchecked")
1926+
@Test
1927+
public void toXmlFromJson19() {
1928+
final String json = "{\n"
1929+
+ " \"a\": {\n"
1930+
+ " },\n"
1931+
+ " \"#encoding\": \"windows-1251\"\n"
1932+
+ "}";
1933+
assertEquals("<?xml version=\"1.0\" encoding=\"windows-1251\"?>\n<a></a>",
1934+
U.toXml((Map<String, Object>) U.fromJson(json)));
1935+
final String json2 = "{\n"
1936+
+ " \"a\": {\n"
1937+
+ " },\n"
1938+
+ " \"#encoding\": \"windows-9999\"\n"
1939+
+ "}";
1940+
assertEquals("<?xml version=\"1.0\" encoding=\"windows-9999\"?>\n<a></a>",
1941+
U.toXml((Map<String, Object>) U.fromJson(json2)));
1942+
}
1943+
19131944
@SuppressWarnings("unchecked")
19141945
@Test
19151946
public void toXml() {

0 commit comments

Comments
 (0)