package jef.tools; import java.util.Date; import java.util.Map.Entry; import jef.json.SerializeConfigEx; import jef.json.XmlJsonSerializer; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.serializer.ObjectSerializer; /** * 提供Json和XML的互相转换 * * @author Administrator * */ public abstract class XMLFastJsonParser { /** * 缺省转换规则。和json-lib中的转换规则一样 * <pre><code> * {"id":576,"desc":"嵇舒门","created":1427266557000,"name":"奚惠","score":38,"modified":1427266815000} * </code></pre> * 将被转换为<code><pre><o> <score type="number">38.0</score> <id type="number">576</id> <desc type="string">嵇舒门</desc> <created type="date">1427266557000</created> <name type="string">奚惠</name> <modified type="date">1427266815000</modified> </o> * </pre></code> * */ public static final XMLFastJsonParser DEFAULT = new XMLJsonParserImpl(); /** * 简易转换规则 * {"created":1427266557000,"desc":"嵇舒门","id":576,"modified":1427266815000,"name":"奚惠","score":38} <?xml version="1.0" encoding="UTF-8"?> <o created="1427266557000" desc="嵇舒门" id="576" modified="1427266815000" name="奚惠" score="38"/> */ public static final XMLFastJsonParser SIMPLE = new SimpleXmlJsonImpl(); public static JSONObject asJsonObject(Object obj) { return (JSONObject) obj; } public static JSONArray asJsonArray(Object obj) { return (JSONArray) obj; } public static JSONObject getAsJSONObject(Object obj) { if (obj instanceof JSONObject) { return (JSONObject) obj; } else { return null; } } public static boolean isJsonObject(Object obj) { return (obj instanceof JSONObject); } public static JSONArray getAsJSONArray(Object obj) { if (obj instanceof JSONArray) { return (JSONArray) obj; } else { return null; } } public static boolean isJsonArray(Object obj) { return (obj instanceof JSONArray); } public static boolean isJsonNull(Object obj) { return obj == null; } public static boolean isJsonPrimitive(Object obj) { if (obj == null) return false; Class<?> clz = obj.getClass(); return clz != JSONArray.class && clz != JSONObject.class; } /** * 将一个JsonObject转换为Document * * @param json * @return */ public abstract Document toDocument(JSONObject json); /** * 将节点还原为JsonObject * * @param node * @return */ public abstract JSONObject toJsonObject(Node node); /** * 将节点还原为JsonObject * * @param node * @return */ public abstract String toJsonString(Node node); static class SimpleXmlJsonImpl extends XMLFastJsonParser { private static SerializeConfigEx XML_GSON; static { XML_GSON = new SerializeConfigEx(); ObjectSerializer nodeSer=new XmlJsonSerializer(); XML_GSON.putHierarchy(org.w3c.dom.Node.class, nodeSer); } public Document toDocument(JSONObject json) { Document doc = XMLUtils.newDocument(); Element root; if (json.size() > 1) { root = XMLUtils.addElement(doc, "o"); for (Entry<String, Object> entry : json.entrySet()) { processJsonProperty(root, entry.getKey(), entry.getValue()); } } else { Entry<String, Object> e = json.entrySet().iterator().next(); root = XMLUtils.addElement(doc, e.getKey()); JSONObject rObj = asJsonObject(e.getValue()); for (Entry<String, Object> entry : rObj.entrySet()) { processJsonProperty(root, entry.getKey(), entry.getValue()); } } return doc; } public JSONObject toJsonObject(Node node) { String s=toJsonString(node); // System.out.println(s); return (JSONObject) JSON.parse(s); } @Override public String toJsonString(Node node) { return JSON.toJSONString(node, XML_GSON); } private void processJsonProperty(Element root, String key, Object value) { if ("#text".equals(key)) { XMLUtils.setText(root, value.toString()); return; } if (isJsonObject(value)) { Element ele = XMLUtils.addElement(root, key == ARRAY_ELEMENT ? XmlJsonSerializer.NAME_COMPLEX_ARRAY_ELEMENT : key); for (Entry<String, Object> entry : asJsonObject(value).entrySet()) { processJsonProperty(ele, entry.getKey(), entry.getValue()); } } else if (isJsonNull(value)) { if (key == ARRAY_ELEMENT) { XMLUtils.addElement(root, XmlJsonSerializer.NAME_PRIMITIVE_ARRAY_ELEMENT, "null"); } else { root.setAttribute(key, "null"); } } else if (isJsonPrimitive(value)) { if (key == ARRAY_ELEMENT) { XMLUtils.addElement(root, XmlJsonSerializer.NAME_PRIMITIVE_ARRAY_ELEMENT, value.toString()); } else { processJsonPrimitive(root, key, value); } } else if (isJsonArray(value)) { processJsonArray(root, key == ARRAY_ELEMENT ? XmlJsonSerializer.NAME_COMPLEX_ARRAY_ELEMENT : key, asJsonArray(value)); } } private static final String ARRAY_ELEMENT = "#e"; private void processJsonArray(Element ele, String key, JSONArray jsonArray) { Element arrNode = XMLUtils.addElement(ele, key); arrNode.setAttribute("_type", "array"); for (Object json : jsonArray) { processJsonProperty(arrNode, ARRAY_ELEMENT, json); } } private void processJsonPrimitive(Element ele, String key, Object p) { if(p instanceof Date){ ele.setAttribute(key, String.valueOf(((Date)p).getTime())); }else if(p instanceof Number){ String floatText= p.toString(); if (floatText.endsWith(".0")) { floatText = floatText.substring(0, floatText.length() - 2); } ele.setAttribute(key, floatText); }else{ ele.setAttribute(key, p.toString()); } } } static class XMLJsonParserImpl extends XMLFastJsonParser { public Document toDocument(JSONObject json) { Document doc = XMLUtils.newDocument(); Element root; root = XMLUtils.addElement(doc, "o"); for (Entry<String, Object> entry : json.entrySet()) { processJsonProperty(root, entry.getKey(), entry.getValue()); } return doc; } /** * 将XML节点转换为Json,XML节点格式必须符合 <o> </o> * * @param doc * @return */ public JSONObject toJsonObject(Node doc) { if (doc.getNodeType() == Node.DOCUMENT_NODE) { doc = ((Document) doc).getDocumentElement(); } JSONObject obj = new JSONObject(); for (Element e : XMLUtils.childElements(doc)) { String name = e.getTagName(); if (e.hasAttribute("null") && e.getAttribute("null").equalsIgnoreCase("true")) { obj.put(name, null); } else if (e.hasAttribute("type")) { obj.put(name, processJsonType(e, e.getAttribute("type"))); } else if (e.hasAttribute("class")) { obj.put(name, processJsonClass(e, e.getAttribute("class"))); } else { throw new IllegalArgumentException("The xml node '" + e.getNodeName() + "' do not have any type/class attribute."); } } return obj; } private void processJsonProperty(Element root, String key, Object value) { Element ele = XMLUtils.addElement(root, key); if (isJsonObject(value)) { ele.setAttribute("class", "object"); for (Entry<String, Object> entry : asJsonObject(value).entrySet()) { processJsonProperty(ele, entry.getKey(), entry.getValue()); } } else if (isJsonNull(value)) { ele.setAttribute("class", "object"); ele.setAttribute("null", "true"); } else if (isJsonPrimitive(value)) { processJsonPrimitive(ele, value); } else if (isJsonArray(value)) { processJsonArray(ele, asJsonArray(value)); } } private void processJsonArray(Element ele, JSONArray jsonArray) { ele.setAttribute("class", "array"); for (Object json : jsonArray) { processJsonProperty(ele, "e", json); } } private void processJsonPrimitive(Element ele, Object p) { if (p instanceof Boolean) { ele.setAttribute("type", "boolean"); XMLUtils.setText(ele, String.valueOf(p)); } else if (p instanceof Number) { ele.setAttribute("type", "number"); XMLUtils.setText(ele, String.valueOf(p)); } else if (p instanceof String) { ele.setAttribute("type", "string"); XMLUtils.setText(ele, (String) p); } else if (p instanceof Date) { ele.setAttribute("type", "date"); Date d = (Date) p; XMLUtils.setText(ele, String.valueOf((d.getTime()))); } else { throw new IllegalArgumentException(p.getClass().getName()); } } private Object processJsonClass(Element ele, String class_) { if ("object".equals(class_)) { return toJsonObject(ele); } else if ("array".equals(class_)) { JSONArray array = new JSONArray(); for (Element e : XMLUtils.childElements(ele, "e")) { if (e.hasAttribute("type")) { array.add(processJsonType(e, e.getAttribute("type"))); } else if (e.hasAttribute("class")) { array.add(processJsonClass(e, e.getAttribute("class"))); } else { throw new IllegalArgumentException("Unknown type:" + class_); } } return array; } else { throw new IllegalArgumentException(); } } private Object processJsonType(Element ele, String type) { if ("boolean".equals(type)) { return StringUtils.toBoolean(XMLUtils.nodeText(ele), false); } else if ("number".equals(type)) { String x = XMLUtils.nodeText(ele); if (x.indexOf('.') > -1) { return StringUtils.toDouble(x, 0d); } else { return StringUtils.toLong(x, 0L); } } else if ("date".equals(type)) { String x = XMLUtils.nodeText(ele); if (StringUtils.isEmpty(x)) return null; return new Date(StringUtils.toLong(x, 0L)); } else { String s = XMLUtils.nodeText(ele); return s; } } @Override public String toJsonString(Node node) { return toJsonObject(node).toJSONString(); } } }