001package com.killcoding.tool; 002 003import java.io.IOException; 004import java.io.StringReader; 005import java.util.ArrayList; 006import java.util.HashMap; 007import java.util.List; 008import java.util.Map; 009 010import javax.xml.parsers.DocumentBuilder; 011import javax.xml.parsers.DocumentBuilderFactory; 012 013import org.w3c.dom.Document; 014import org.w3c.dom.Element; 015import org.w3c.dom.Node; 016import org.w3c.dom.NodeList; 017import org.w3c.dom.Attr; 018import org.xml.sax.InputSource; 019 020public class XmlParser { 021 022 private String xml; 023 private String rootName; 024 private Map<String, Object> root; 025 026 public XmlParser(String xml) throws Exception { 027 super(); 028 this.xml = xml; 029 root = xml2Map(this.xml); 030 } 031 032 public void put(String name, Map<String, Object> map) { 033 root.put(getShortName(name), map); 034 } 035 036 public String getRootName() { 037 return rootName; 038 } 039 040 public Object get(String... keys) { 041 Object o = null; 042 if (root == null) 043 return null; 044 045 Map<String, Object> m = (Map<String, Object>) root; 046 for (int i = 0; i < keys.length; i++) { 047 o = m.get(keys[i]); 048 if (o == null) { 049 break; 050 } else { 051 if (o instanceof Map) { 052 m = (Map<String, Object>) o; 053 continue; 054 } else { 055 if (i != keys.length - 1) 056 o = null; 057 } 058 } 059 } 060 if (o != null && o instanceof String) { 061 return ((String) o).trim(); 062 } 063 return o; 064 } 065 066 public List<Object> getList(String... keys) { 067 List<Object> list = new ArrayList<Object>(); 068 Object o = null; 069 if (root == null) 070 return null; 071 072 Map<String, Object> m = (Map<String, Object>) root; 073 for (int i = 0; i < keys.length; i++) { 074 o = m.get(keys[i]); 075 if (o == null) { 076 break; 077 } else { 078 if (o instanceof Map) { 079 m = (Map<String, Object>) o; 080 continue; 081 } else { 082 if (i != keys.length - 1) 083 o = null; 084 } 085 } 086 } 087 if (o != null) { 088 if (o instanceof String) { 089 o = ((String) o).trim(); 090 list.add(o); 091 } 092 if (o instanceof List) { 093 list.addAll((List) o); 094 } else { 095 list.add(o); 096 } 097 } 098 return list; 099 } 100 101 public Object path(String paths) { 102 if (paths == null) return null; 103 return get(paths.trim().split("\\.")); 104 } 105 106 public List<Object> pathList(String paths) { 107 if (paths == null) return null; 108 return getList(paths.trim().split("\\.")); 109 } 110 111 public Map<String, Object> xml2Map(String xml) throws Exception { 112 Map<String, Object> map = new HashMap<>(); 113 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 114 factory.setNamespaceAware(false); 115 factory.setValidating(false); 116 117 DocumentBuilder builder = factory.newDocumentBuilder(); 118 Document document = builder.parse(new InputSource(new StringReader(xml))); 119 120 Element rootElement = document.getDocumentElement(); 121 rootName = rootElement.getNodeName(); 122 123 NodeList childNodes = rootElement.getChildNodes(); 124 for (int i = 0; i < childNodes.getLength(); i++) { 125 Node node = childNodes.item(i); 126 if (node.getNodeType() == Node.ELEMENT_NODE) { 127 Element element = (Element) node; 128 processElement(element, map); 129 } 130 } 131 return map; 132 } 133 134 private void processElement(Element element, Map<String, Object> parentMap) { 135 String elementName = element.getNodeName(); 136 NodeList children = element.getChildNodes(); 137 138 boolean hasElementChildren = false; 139 for (int i = 0; i < children.getLength(); i++) { 140 if (children.item(i).getNodeType() == Node.ELEMENT_NODE) { 141 hasElementChildren = true; 142 break; 143 } 144 } 145 146 if (!hasElementChildren) { 147 String textContent = getElementText(element); 148 handleValue(parentMap, elementName, textContent, element); 149 } else { 150 Map<String, Object> childMap = new HashMap<>(); 151 for (int i = 0; i < children.getLength(); i++) { 152 Node child = children.item(i); 153 if (child.getNodeType() == Node.ELEMENT_NODE) { 154 processElement((Element) child, childMap); 155 } 156 } 157 158 if (childMap.isEmpty()) { 159 String textContent = getElementText(element); 160 handleValue(parentMap, elementName, textContent, element); 161 } else { 162 handleMap(parentMap, elementName, childMap, element); 163 } 164 } 165 } 166 167 private void handleValue(Map<String, Object> map, String key, Object value, Element element) { 168 Object existingValue = map.get(key); 169 170 if (existingValue == null) { 171 map.put(getShortName(key), blank(value)); 172 map.put("@" + getShortName(key), parseAttributes(element)); 173 } else if (existingValue instanceof List) { 174 ((List<Object>) existingValue).add(blank(value)); 175 176 Object existingAttrs = map.get("@" + getShortName(key)); 177 if (existingAttrs instanceof List) { 178 ((List<Object>) existingAttrs).add(parseAttributes(element)); 179 } 180 } else { 181 List<Object> valueList = new ArrayList<>(); 182 valueList.add(existingValue); 183 valueList.add(blank(value)); 184 map.put(getShortName(key), valueList); 185 186 List<Object> attrList = new ArrayList<>(); 187 attrList.add(map.get("@" + getShortName(key))); 188 attrList.add(parseAttributes(element)); 189 map.put("@" + getShortName(key), attrList); 190 } 191 } 192 193 private void handleMap(Map<String, Object> map, String key, Map<String, Object> value, Element element) { 194 Object existingValue = map.get(key); 195 196 if (existingValue == null) { 197 map.put(getShortName(key), value); 198 map.put("@" + getShortName(key), parseAttributes(element)); 199 } else if (existingValue instanceof List) { 200 ((List<Object>) existingValue).add(value); 201 202 Object existingAttrs = map.get("@" + getShortName(key)); 203 if (existingAttrs instanceof List) { 204 ((List<Object>) existingAttrs).add(parseAttributes(element)); 205 } 206 } else { 207 List<Object> valueList = new ArrayList<>(); 208 valueList.add(existingValue); 209 valueList.add(value); 210 map.put(getShortName(key), valueList); 211 212 List<Object> attrList = new ArrayList<>(); 213 attrList.add(map.get("@" + getShortName(key))); 214 attrList.add(parseAttributes(element)); 215 map.put("@" + getShortName(key), attrList); 216 } 217 } 218 219 public static Map<String, String> parseAttributes(Element element) { 220 Map<String, String> atts = new HashMap<>(); 221 if (element.hasAttributes()) { 222 for (int i = 0; i < element.getAttributes().getLength(); i++) { 223 Attr attr = (Attr) element.getAttributes().item(i); 224 atts.put(attr.getName(), attr.getValue()); 225 } 226 } 227 return atts; 228 } 229 230 private String getElementText(Element element) { 231 StringBuilder text = new StringBuilder(); 232 NodeList childNodes = element.getChildNodes(); 233 234 for (int i = 0; i < childNodes.getLength(); i++) { 235 Node node = childNodes.item(i); 236 if (node.getNodeType() == Node.TEXT_NODE) { 237 text.append(node.getNodeValue()); 238 } 239 } 240 241 return text.toString(); 242 } 243 244 public Map<String, Object> getRoot() { 245 return root; 246 } 247 248 private static Object blank(Object value) { 249 return (value == null || value.toString().trim().equals("")) ? null : value; 250 } 251 252 protected static String join(List<String> list, String conjunction) { 253 StringBuilder sb = new StringBuilder(); 254 boolean first = true; 255 for (String item : list) { 256 if (first) 257 first = false; 258 else 259 sb.append(conjunction); 260 261 sb.append(item.trim()); 262 } 263 return sb.toString(); 264 } 265 266 private String getShortName(String nodeName) { 267 return nodeName.replaceFirst("^.*:",""); 268 } 269 270} 271