XML文件解析-DOM4J方式和SAX方式
最近遇到的工作内容都是和xml内容解析相关的.
1图片数据以base64编码的方式保存在xml的一个标签中,xml文件通过接口的方式发送给我,然后我去解析出图片数据,对图片进行进一步处理.
2.xml内容保存在blob字段中,然后jdbc读取blob字段获取xml内容进行解析.
解析的方法挺简单的,网上有很多种,主要有SAX,DOM4J等.
先来揭晓一下DOM4J是如何解析xml文件的,话不多少,直接上码.
/** * 获取xml文件绝对路径 */ private String getFilePath() { String fileName = "test.xml"; String filePath = System.getProperty("user.dir").replace("\\", "/") return filePath+"/"+fileName; }
/** * 解析获取xml节点数据 */ private Map<String,String> parseXml(String filePath) { File xmlFile = new File(filepath); SAXReader reader = new SAXReader(); Map<String,String> paramMap = new HashMap<String,String>(); try { Document document = reader.read(xmlFile); Element rootElement = document.getRootElement(); Element nameElement = rootElement.element("name"); String name = nameElement.getText(); paramMap.put("name",name); Element telElement = rootElement.element("tel"); String tel = telElement.getText(); paramMap.put("tel",tel); Element addressElement = rootElement.element("address"); String address = addressElement.getText(); paramMap.put("address",address); } catch (Exception e) { logger.error("解析xml文件出错", e); } return paramMap; }
解析的xml文档如下
<?xml version="1.0" encoding="UTF-8"?> <RootElement> <name>黑天鹅</name> <tel>12345678</tel> <address>反脆弱训练基地</address> </RootElement>
然后我们揭晓一下SAX是如何进行xml解析的,直接上码.
/** * xml文件内容解析 * * @param fileName * @return map * @throws Exception */ public Map<String, String> parseXmlContent(byte[] fileContent) { Map<String, String> dataMap = new HashMap<String, String>(); if (fileContent.length <= 0) { logger.error("获取文件流出错,文件流为空"); return null; } try { ByteArrayInputStream input = new ByteArrayInputStream(fileContent); SAXParserFactory parsefactory = SAXParserFactory.newInstance(); SAXParser parser = parsefactory.newSAXParser(); SAXParseHandler parseHandler = new SAXParseHandler(); parser.parse(input, new SAXParseHandler()); dataMap = parseHandler.getXmlMap(); } catch (Exception e) { System.out.println(e); logger.error("xml文件解析错误", e); return null; } return dataMap; }
SAX自定义一个解析类.
class SAXParseHandler extends DefaultHandler { private static Map<String, String> map; private String tagName; private StringBuilder sb; public void startDocument() throws SAXException { super.startDocument(); map = new HashMap<String, String>(); } public void endDocument() throws SAXException { super.endDocument(); } /** * 获取文档属性,内容,执行多次 */ public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { super.startElement(uri, localName, qName, attributes); //在此可以获取标签属性内容 this.tagName = qName; sb = new StringBuilder(); } /** * 获取标签值,执行多次 */ public void endElement(String uri, String localName, String qName) throws SAXException { String data = sb.toString(); if (StringUtils.isNotBlank(tagName)) { switch (tagName) { case "name": map.put("name", data); break; case "tel": map.put("tel", data); break; case "address": map.put("address", data); break; default: break; } } } public Map<String, String> getXmlMap() { return map; } /** * 获取整个文档数据 */ public void characters(char[] ch, int start, int length) throws SAXException { sb.append(new String(ch, start, length)); }
测试主方法(开发时候用的,按需调试即可)
public static void main(String[] args) throws IOException { File file = new File("F:\\test.xml"); FileInputStream input = new FileInputStream(file); ByteArrayOutputStream output = new ByteArrayOutputStream(); byte[] bt = new byte[1024]; int n; while((n = input.read(bt)) != -1){ output.write(bt, 0, n); } input.close(); output.close(); byte[] filebyte = output.toByteArray(); XmlParser par = new XmlParser(); Map<String, String> dataMap = par.parseXmlContent(filebyte); System.out.println(dataMap); }
在解析xml的时候遇到了很多奇葩坑,用户标签不规范,发过来的数据没有标签的,还有发过来空文件的,真真够了.
尤其在解析blob字段中的xml内容数据时,也存在一些坑,到时候解决了在更新.