java利用SAX解析XML
程序员文章站
2022-05-28 08:31:49
...
java利用SAX解析XML
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class XmlTreateUtil extends DefaultHandler {
@Override
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
depth++;
leafValue = null;
isChanged = true;
if (startTagList.size() == 0) {
root.setTagName(qName);
if (attributes != null) {
for (int i = 0; i < attributes.getLength(); i++) {
String attributeName = attributes.getQName(i);
if ("schema".equals(attributeName)) {
root.setSchema(attributes.getValue("schema"));
} else if ("version".equals(attributeName)) {
root.setVersion(attributes.getValue("version"));
} else {
root.addAttribute(attributes.getQName(i),
attributes.getValue(i));
}
}
}
cdoMap.put(qName, root);
}
startTagList.add(qName);
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
depth--;
if (null != leafValue && !"".equals(qName)) {
if(qName.contains(":")){
leafElementMap.put(qName.substring(qName.indexOf(":")+1).toLowerCase(), leafValue);
}else{
leafElementMap.put(qName.toLowerCase(), leafValue);
}
leafValue = null;
}
int n = 0;
XMLElement cdo = null;
for (int index = startTagList.size() - 1; index > 0; index--) {
if (startTagList.get(index).equals(qName)) {
// 父节点判断
if (cdoMap.get(qName) != null) {
cdoMap.remove(qName);
startTagList.remove(qName);
return;
}
if (n <= 0) {
cdo = processCdoMap(index - 1);
cdo.addChild(qName, value);
}
startTagList.remove(qName);
break;
} else {
n++;
}
}
}
private XMLElement processCdoMap(int i) {
if (i == 0) {
return root;
}
XMLElement cdo = cdoMap.get(startTagList.get(i));
if (cdo == null) {
cdo = new XMLElement();
cdo.setTagName(startTagList.get(i));
cdoMap.put(startTagList.get(i), cdo);
XMLElement root = processCdoMap(i - 1);
root.addChild(startTagList.get(i), cdo);
}
return cdo;
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
leafValue = new String(ch, start, length);
if (!isChanged) {
value.append(new String(ch, start, length));
} else {
value = new StringBuffer(new String(ch, start, length));
}
isChanged = false;
}
public XMLElement parseXmlReqString(String xmlReq) {
StringReader read = new StringReader(xmlReq);
InputSource source = new InputSource(read);
parse(source);
root.setLeafElementMap(leafElementMap);
return root;
}
public XMLElement parseXmlFromFile(String fileName) {
try {
InputSource source = new InputSource(new FileInputStream(fileName));
parse(source);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
root.setLeafElementMap(leafElementMap);
return root;
}
private void parse(InputSource source) {
SAXParser sp;
SAXParserFactory sf = SAXParserFactory.newInstance();
try {
sp = sf.newSAXParser();
sp.parse(source, this);
} catch (Exception e) {
e.printStackTrace();
}
}
// 标签值
private StringBuffer value;
private List<String> startTagList = new ArrayList<String>();
private Map<String, XMLElement> cdoMap = new HashMap<String, XMLElement>();
private XMLElement root = new XMLElement();
// 是否是同一个标签
private boolean isChanged;
int depth = 0;
/**
* 去重后的叶子节点,key为节点名称,value为文本值
*/
private Map<String, String> leafElementMap = new HashMap<String, String>();
String leafValue = null;
}
import java.io.PrintWriter;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import javax.servlet.http.HttpServletResponse;
import sun.misc.BASE64Decoder;
@SuppressWarnings("restriction")
public class XMLElement implements Serializable {
public XMLElement() {
}
public XMLElement(String version, String schema) {
this.setVersion(version);
this.setSchema(schema);
}
public XMLElement(String version, String schema, Map<String, Object> map) {
this(version, schema);
Set<Entry<String, Object>> set = map.entrySet();
for (Entry<String, Object> entry : set) {
this.addChild(entry.getKey(), entry.getValue());
}
}
public XMLElement(String version, String schema, String nameValuePair) {
this(version, schema);
String[] nameValuePairs = nameValuePair.split("\\,");
for (String nameValue : nameValuePairs) {
this.addChild(nameValue.split("\\:")[0], nameValue.split("\\:")[1]);
}
}
public String getVersion() {
return version;
}
public void setVersion(String version) {
this.version = version;
addAttribute("version", version);
}
public String getSchema() {
return schema;
}
public void setSchema(String schema) {
this.schema = schema;
addAttribute("schema", schema);
}
public void setTagName(String tagName) {
this.tagName = tagName;
}
public void addAttribute(String key, String value) {
this.attributeMap.put(key, value);
}
@SuppressWarnings("unchecked")
public void addChild(String key, Object value) {
if (value == null) {
return;
}
childList.add(key);
// 判断当前map中是否已有值
List lis = this.childMap.get(key);
if (lis != null) {
lis.add(value);
this.childMap.put(key, lis);
} else {
// childMap
List list = new ArrayList();
list.add(value);
this.childMap.put(key, list);
}
}
/**
* 添加唯一性子节点(会删掉旧有值,有的话)
*
* @param key
* @param value
*/
public void addUniqueChild(String key, Object value) {
if (value == null) {
return;
}
childList.add(key);
List<Object> list = new ArrayList<Object>();
list.add(value);
this.childMap.put(key, list);
}
/**
* 替换childMap中的key为给定key,替换规则:不区分大小写的情况下2个key相同
*
* @param key
*/
public void replaceChildKey(String key) {
try {
Set<Entry<String, List<?>>> set = childMap.entrySet();
String oldKey = null;
for (Entry<String, List<?>> entry : set) {
if (key.equals(entry.getKey())) {
break;
}
if (key.equalsIgnoreCase(entry.getKey())) {
oldKey = entry.getKey();
}
}
if (oldKey != null) {
// 添加新key
addChild(key, childMap.get(oldKey).get(0));
// 删除旧key
removeChild(oldKey);
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 删除节点
*
* @param oldKey
*/
private void removeChild(String oldKey) {
childList.remove(oldKey);
childMap.remove(oldKey);
}
/**
* cdo对象转换成xml字符串
*/
public String toXML() {
StringBuffer sb = new StringBuffer();
return toXML(sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"),
0);
}
private String toXML(StringBuffer sb, int n) {
this.validKey = new HashMap<String, Boolean>();
appendTabs(sb, n);
sb.append("<").append(tagName);
// 处理属性节点
processAttributeMap(sb);
sb.append(">\n");
// 处理子节点
processChildMap(sb, n + 1);
appendTabs(sb, n);
sb.append("</").append(tagName).append(">\n");
return sb.toString();
}
private void appendTabs(StringBuffer sb, int n) {
for (int i = 0; i < n; i++) {
sb.append("\t");
}
}
public double divide(String key, double divide, int scale, int roundingMode) {
return BigDecimal.valueOf(Double.valueOf(this.getStringValue(key)))
.divide(BigDecimal.valueOf(divide), scale, roundingMode)
.doubleValue();
}
public double multiply(String key, double divide, int scale,
int roundingMode) {
return BigDecimal.valueOf(Double.valueOf(this.getStringValue(key)))
.multiply(BigDecimal.valueOf(divide))
.setScale(scale, roundingMode).doubleValue();
}
/**
* @param sb
*/
@SuppressWarnings("unchecked")
private void processChildMap(StringBuffer sb, int n) {
for (int i = 0; i < childList.size(); i++) {
String key = childList.get(i);
if (validKey.get(key) != null && validKey.get(key).booleanValue()) {
continue;
} else {
validKey.put(key, true);
}
Object value = childMap.get(key);
if (value instanceof XMLElement) {
((XMLElement) value).toXML(sb, n);
} else if (value instanceof List) {
List list = (List) value;
for (Object object : list) {
if (object instanceof XMLElement) {
((XMLElement) object).toXML(sb, n);
} else if (object instanceof XMLElement[]) {
for (XMLElement cdo : (XMLElement[]) object) {
cdo.toXML(sb, n);
}
} else {
appendTabs(sb, n);
sb.append("<").append(key).append(">").append(object)
.append("</").append(key).append(">\n");
}
}
} else {
appendTabs(sb, n);
sb.append("<").append(key).append(">").append(value)
.append("</").append(key).append(">\n");
}
}
}
/**
* @param sb
*/
private void processAttributeMap(StringBuffer sb) {
Set<Entry<String, String>> set = attributeMap.entrySet();
Iterator<Entry<String, String>> it = set.iterator();
while (it.hasNext()) {
Entry<String, String> entry = it.next();
sb.append(" ").append(entry.getKey()).append("=\"")
.append(entry.getValue()).append("\"");
}
}
/**
* cdo对象转换成json格式字符串
*/
public String toJSON() {
StringBuffer sb = new StringBuffer();
this.validKey = new HashMap<String, Boolean>();
// 处理子节点
for (int i = 0; i < childList.size(); i++) {
String key = childList.get(i);
if (validKey.get(key) != null && validKey.get(key).booleanValue()) {
continue;
} else {
validKey.put(key, true);
}
Object value = childMap.get(key);
if (value instanceof XMLElement) {
sb.append("\"").append(key).append("\":[")
.append(((XMLElement) value).toJSON()).append("],");
} else if (value instanceof List) {
List list = (List) value;
for (int j = 0; j < list.size(); j++) {
Object object = list.get(j);
if (object instanceof XMLElement) {
sb.append("\"").append(key).append("\":{")
.append(((XMLElement) object).toJSON())
.append("},");
} else if (object instanceof XMLElement[]) {
XMLElement[] cdos = (XMLElement[]) object;
sb.append("\"").append(key).append("\":[");
String temp = "";
for (XMLElement cdo : cdos) {
temp += "{" + cdo.toJSON() + "},";
}
temp = temp.substring(0, temp.length() - 1);
sb.append(temp).append("],");
} else {
sb.append("\"").append(key).append("\":\"")
.append(object).append("\",");
}
}
} else {
sb.append("\"").append(key).append("\":\"").append(value)
.append("\",");
}
}
return sb.toString().length() > 0 ? sb.toString().substring(0,
sb.toString().length() - 1) : sb.toString();
}
/**
* 输出xml格式字符串到指定response中
*
* @param response
*/
public void printJSON(HttpServletResponse response) {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out;
try {
out = response.getWriter();
out.print("{" + toJSON() + "}");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 输出xml格式字符串到指定response中
*
* @param response
*/
public void printXML(HttpServletResponse response) {
response.setContentType("text/xml;charset=UTF-8");
PrintWriter out;
try {
out = response.getWriter();
out.print(toXML());
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取当前对象中给定attribute值
*
* @param key
* @return
*/
public String getAttributeValue(String key) {
return this.attributeMap.get(key);
}
/**
* 获取当前对象中给定的子节点值
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public Object getChildObject(String key) {
return ((List) getChildValue(key)).get(0);
}
/**
* 获取当前对象中给定的子节点值
*
* @param key
* @return
*/
public Object getChildValue(String key) {
return this.childMap.get(key) == null ? null : this.childMap.get(key);
}
/**
* 获取给定key值的List对象,List中的值可能为String、CDO类型
*
* @param key
* @return
*/
public List<?> getListValue(String key) {
return (List<?>) getChildValue(key);
}
/**
* 获取CDO数组
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public XMLElement[] getCdoArrayValue(String key) {
List<XMLElement[]> value = (List<XMLElement[]>) this.getListValue(key);
if (value != null && value.size() > 0) {
return value.get(0);
} else {
return null;
}
}
@SuppressWarnings("unchecked")
public XMLElement getCdoValue(String key) {
List<XMLElement> value = (List<XMLElement>) this.getListValue(key);
return value == null ? null : value.get(0);
}
/**
* 获取String数组
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public String[] getStringArrayValue(String key) {
List<String> value = (List<String>) this.getListValue(key);
return value == null ? null : (String[]) value.toArray();
}
/**
* 获取标签值
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public String getStringValue(String key) {
return this.getChildValue(key) == null ? null : ((List) this
.getChildValue(key)).get(0).toString();
}
public String getBigDecimalString(String key) {
return new java.text.DecimalFormat("#.00").format(Double
.valueOf(getStringValue(key)));
}
@SuppressWarnings("unchecked")
public Boolean getBooleanValue(String key) {
return (Boolean) (this.getChildValue(key) == null ? false
: ((List) this.getChildValue(key)).get(0));
}
/**
* 获取标签值
*
* @param key
* @return
*/
@SuppressWarnings("unchecked")
public Integer getIntegerValue(String key) {
return this.getChildValue(key) == null ? null : Integer
.parseInt(((List) this.getChildValue(key)).get(0).toString());
}
/**
* 获取标签值
*
* @param key
* @return
*/
public Long getLongValue(String key) {
return this.getChildValue(key) == null ? null : Long
.parseLong(((List) this.getChildValue(key)).get(0).toString());
}
/**
* 判断是否存在对应的key值
*
* @param key
* @return true,false
*/
public boolean hasChild(String key) {
return this.childMap.containsKey(key);
}
public Map<String, List<?>> getChildMap() {
return this.childMap;
}
public byte[] getBytesFromBASE64(String b) throws Exception {
if (b == null)
return null;
BASE64Decoder decode = new BASE64Decoder();
return decode.decodeBuffer(b);
}
/**
* 把非CDO对象的子节点遍历到Map<String, String>中
*
* @return Map<String, String>
*/
public Map<String, Object> getReqeustMap() {
Set<Entry<String, List<?>>> set = childMap.entrySet();
Map<String, Object> returnMap = new HashMap<String, Object>();
for (Entry<String, List<?>> entry : set) {
List<?> list = entry.getValue();
if (list != null && list.size() != 0) {
Object object = list.get(0);
if (object instanceof XMLElement) {
continue;
}
// 判断是否是byte[]类型:判断规则value值的长度大于1000
if (!(object instanceof byte[])
&& object.toString().length() > 1000) {
try {
returnMap.put(entry.getKey(),
getBytesFromBASE64(object.toString()));
} catch (Exception e) {
e.printStackTrace();
}
} else {
returnMap.put(entry.getKey(), object.toString());
}
}
}
return returnMap;
}
/**
* 把给定的Map对象中解析成CDO对象,数据存储到childMap属性中
*
* @param map
* @return
*/
public static XMLElement getCDOFromMap(Map<String, String> map) {
XMLElement cdo = new XMLElement();
Set<Entry<String, String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
cdo.addChild(entry.getKey(), entry.getValue());
}
return cdo;
}
/**
* 把给定的Map对象中解析成CDO对象,数据存储到childMap属性中
*
* @param map
* @return
*/
public void setChildFromMap(Map<String, String> map) {
Set<Entry<String, String>> set = map.entrySet();
for (Entry<String, String> entry : set) {
this.addChild(entry.getKey(), entry.getValue());
}
}
/**
* 所要执行的sql标识: namespace.sqlId
*/
public void setNamespaceSql(String namespaceSql) {
this.namespaceSql = namespaceSql;
}
public String getNamespaceSql() {
return namespaceSql;
}
@Override
public String toString() {
return toXML();
}
public static XMLElement fromXML(String reqXml) {
XmlTreateUtil dto = new XmlTreateUtil();
if(null!=reqXml&&!reqXml.contains("<?xml ")){
reqXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+ reqXml;
}
return dto.parseXmlReqString(reqXml);
}
public String getLeafValue(String key) {
if(null==key) return null;
return leafElementMap.get(key.toLowerCase());
}
public void setLeafElementMap(Map<String, String> leafElementMap) {
this.leafElementMap = leafElementMap;
}
private static final long serialVersionUID = 1L;
private Map<String, Boolean> validKey;
private String version;
private String schema;
private Map<String, String> attributeMap = new HashMap<String, String>();
private Map<String, List<?>> childMap = new HashMap<String, List<?>>(20);
private String tagName = "root";
private List<String> childList = new ArrayList<String>(20);
public static XMLElement NOT_POST = new XMLElement("1.0", "accessLimit",
"return:9011,description:请求类型错误,要求为POST请求。");
public static XMLElement OK = new XMLElement("1.0", "processSuccess",
"return:00,description:操作成功。");
public static XMLElement ERROR = new XMLElement("1.0", "processFail",
"return:01,description:操作失败。");
private String namespaceSql;
/**
* 去重后的叶子节点,key为节点名称,value为文本值
*/
private Map<String, String> leafElementMap = new HashMap<String, String>();
public static void main(String[] args) {
String xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>"+
"<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"" +
" xmlns:SOAP-ENC=\"http://schemas.xmlsoap.org/soap/encoding/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:comm3=\"http://www.chinatelecom.com.cn/schema/ctcc/common/v2_1\"" +
" xmlns:sms7=\"http://www.chinatelecom.com.cn/schema/ctcc/sms/notification/v2_1/local\">" +
" <SOAP-ENV:Header>" +
" <comm3:NotifySOAPHeader>" +
" <spRevId>spRevId</spRevId>" +
" <spRevpassword>password</spRevpassword>" +
" <spId>1234</spId>" +
" <SAN>tel:199999999</SAN>" +
" <linkId>1111122222222222</linkId>" +
" </comm3:NotifySOAPHeader>" +
" </SOAP-ENV:Header>" +
" <SOAP-ENV:Body>" +
" <sms7:notifySmsReception>" +
" <sms7:registrationIdentifier>3444444444444444</sms7:registrationIdentifier>" +
" <sms7:message>" +
" <message>sp</message>" +
" <senderAddress>tel:sdfffffffff</senderAddress>" +
" <smsServiceActivationNumber>tel:sdffffff</smsServiceActivationNumber>" +
" </sms7:message>" +
" </sms7:notifySmsReception>" +
" </SOAP-ENV:Body>" +
"</SOAP-ENV:Envelope>";
XMLElement root = XMLElement.fromXML(xml);
System.out.println(root.toJSON());
// System.out.println(new HashMap());
// System.out.println((((List<CDO>)root.getChildValue("mobileVerifyParam")).get(0)).getListValue("contactName"));
}
}
上一篇: Ubuntu 14.04下 MySQL 开启远程连接
下一篇: SAX解析操作