package com.example.lxb.awaken.model; import com.example.lxb.awaken.SpeechApp; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; /** * 使用Sax解析xml文档 * <p> * Created by lxb on 2017/4/26. */ public class ParseXMLSAX { private static ParseXMLSAX parseXMLSAX; public static ParseXMLSAX getInstance(){ if(parseXMLSAX == null){ parseXMLSAX = new ParseXMLSAX(); } return parseXMLSAX; } /** * 获取assets文件 * * @param path * @return */ public InputStream getFileInputStream(String path) { try { return SpeechApp.getInstance().getAssets().open(path); } catch (IOException e) { e.printStackTrace(); } return null; } /** * 解析xml文档 * * @param path * @return * @throws Exception */ public List<VoiceEntity> parse(String path) throws Exception { InputStream is = getFileInputStream(path); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); SaxXmlHandler handler = new SaxXmlHandler(); parser.parse(is, handler); return handler.getvoiceEntitys(); } /** * DefaultHandler是一个事件处理器,可以接收解析器报告的所有事件,处理所发现的数据 * */ private class SaxXmlHandler extends DefaultHandler { private List<VoiceEntity> voiceEntitys; private VoiceEntity voiceEntity; private StringBuilder builder; public List<VoiceEntity> getvoiceEntitys() { return voiceEntitys; } @Override public void startDocument() throws SAXException { // TODO Auto-generated method stub super.startDocument(); voiceEntitys = new ArrayList<>(); builder = new StringBuilder(); } @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // TODO Auto-generated method stub super.startElement(uri, localName, qName, attributes); if (localName.equals("item")) { voiceEntity = new VoiceEntity(); } builder.setLength(0); } @Override public void characters(char[] ch, int start, int length) throws SAXException { // TODO Auto-generated method stub super.characters(ch, start, length); builder.append(ch, start, length); //将读取的字符数组追加到builder中 } @Override public void endElement(String uri, String localName, String qName) throws SAXException { // TODO Auto-generated method stub super.endElement(uri, localName, qName); if (localName.equals("id")) { voiceEntity.setID(Integer.parseInt(builder.toString())); } else if (localName.equals("type")) { voiceEntity.setType(Integer.parseInt(builder.toString())); } else if (localName.equals("key")) { voiceEntity.setKey(Integer.parseInt(builder.toString())); } else if (localName.equals("cmd")) { voiceEntity.setCmd(builder.toString()); } else if (localName.equals("item")) { voiceEntitys.add(voiceEntity); } } } }
对外接口类:
package com.example.lxb.awaken.speech.util; import com.example.lxb.awaken.SpeechApp; import com.example.lxb.awaken.model.ParseXMLSAX; import com.example.lxb.awaken.model.VoiceEntity; import com.iflytek.cloud.util.ResourceUtil; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; /** * Xml结果解析类 */ public class XmlParser { public static String parseNluResult(String xml) { StringBuffer buffer = new StringBuffer(); try { // DOM builder DocumentBuilder domBuilder = null; // DOM doc Document domDoc = null; // init DOM DocumentBuilderFactory domFact = DocumentBuilderFactory.newInstance(); domBuilder = domFact.newDocumentBuilder(); InputStream is = new ByteArrayInputStream(xml.getBytes()); domDoc = domBuilder.parse(is); // 获取根节点 Element root = (Element) domDoc.getDocumentElement(); Element raw = (Element)root.getElementsByTagName("rawtext").item(0); buffer.append("【识别结果】" + raw.getFirstChild().getNodeValue()); buffer.append("\n"); Element e = (Element)root.getElementsByTagName("result").item(0); Element focus = (Element)e.getElementsByTagName("focus").item(0); buffer.append("【FOCUS】" + focus.getFirstChild().getNodeValue()); buffer.append("\n"); Element action = (Element)e.getElementsByTagName("action").item(0); Element operation = (Element)action.getElementsByTagName("operation").item(0); buffer.append("【ACTION】" + operation.getFirstChild().getNodeValue()); buffer.append("\n"); }catch(Exception e){ e.printStackTrace(); }; buffer.append("【ALL】" + xml); return buffer.toString(); } /** * 使用DOM解析方式 * DOM是基于树形结构的的节点或信息片段的集合,允许开发人员使用DOM API遍历XML树、检索所需数据。 * 分析该结构通常需要加载整个文档和构造树形结构,然后才可以检索和更新节点信息。 * 由于DOM在内存中以树形结构存放,因此检索和更新效率会更高。但是对于特别大的文档,解析和加载整个文档将会很耗资源。 * * * @param path * @return */ public static List<VoiceEntity> parseXMLByDom(String path){ InputStream is = null; try { is = SpeechApp.getInstance().getAssets().open(path); List<VoiceEntity> s = new ArrayList<>(); DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); //取得DocumentBuilderFactory实例 DocumentBuilder builder = factory.newDocumentBuilder(); //从factory获取DocumentBuilder实例 Document doc = builder.parse(is); //解析输入流 得到Document实例 Element rootElement = doc.getDocumentElement(); NodeList items = rootElement.getElementsByTagName("item"); for (int i = 0; i < items.getLength(); i++) { VoiceEntity depart = new VoiceEntity(); Node item = items.item(i); NodeList properties = item.getChildNodes(); for (int j = 0; j < properties.getLength(); j++) { Node property = properties.item(j); String nodeName = property.getNodeName(); if (nodeName.equals("ID")) { depart.setID(Integer.parseInt(property.getFirstChild().getNodeValue())); } else if (nodeName.equals("type")) { depart.setType(Integer.parseInt(property.getFirstChild().getNodeValue())); } else if (nodeName.equals("key")) { depart.setKey(Integer.parseInt(property.getFirstChild().getNodeValue())); } } s.add(depart); } return s; } catch (IOException e) { e.printStackTrace(); } catch (ParserConfigurationException e) { e.printStackTrace(); } catch (SAXException e) { e.printStackTrace(); } return null; } /** * SAX:优点是解析速度快,占用内存少。非常适合在Android移动设备中使用 * * @param path */ public static List<VoiceEntity> parseXMLBySAX(String path){ try { return ParseXMLSAX.getInstance().parse(path); } catch (Exception e) { e.printStackTrace(); } return null; } }
信息实体类:
package com.example.lxb.awaken.model; /** * Created by lxb on 2017/4/26. */ public class VoiceEntity extends XMLBase{ private int ID; private int type; private int key; private String cmd; public int getID() { return ID; } public void setID(int ID) { this.ID = ID; } public int getType() { return type; } public void setType(int type) { this.type = type; } public int getKey() { return key; } public void setKey(int key) { this.key = key; } public String getCmd() { return cmd; } public void setCmd(String cmd) { this.cmd = cmd; } }
测试接口:
long start = System.currentTimeMillis(); try { System.out.println("88-----------"+XmlParser.parseXMLBySAX("volinfo.xml").size()); //文件记得放在assets目录下 long end = System.currentTimeMillis(); } catch (Exception e) { e.printStackTrace(); }
volinfo.xml文件内容:
<?xml version="1.0" encoding="UTF-8"?> <volbook> <!-- 音量加 --> <item> <ID>0</ID> <type>1</type> <key>518</key> <cmd>no</cmd> </item> <!-- 音量减 --> <item> <ID>1</ID> <type>1</type> <key>517</key> <cmd>no</cmd> </item> <!-- 亮度加 --> <item> <ID>2</ID> <type>1</type> <key>520</key> <cmd>no</cmd> </item> <!-- 亮度减 --> <item> <ID>3</ID> <type>1</type> <key>519</key> <cmd>no</cmd> </item> <!-- 关机操作 --> <item> <ID>4</ID> <type>0</type> <key>506</key> <cmd>reboot -p</cmd> </item> <!-- 待机功能 --> <item> <ID>5</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 照相机调用 摄像机呼出 --> <item> <ID>6</ID> <type>1</type> <key>601</key> <cmd>no</cmd> </item> <item> <ID>7</ID> <type>1</type> <key>601</key> <cmd>no</cmd> </item> <!-- 音乐功能 --> <item> <ID>8</ID> <type>1</type> <key>600</key> <cmd>no</cmd> </item> <!-- 电影功能 --> <item> <ID>9</ID> <type>0</type> <key>506</key> <cmd>am start -n com.actions.demomovie/.FileBrowserActivity</cmd> </item> <!-- 系统设置 --> <item> <ID>10</ID> <type>0</type> <key>506</key> <cmd>am start -n com.android.settings/.Settings</cmd> </item> <!-- 浏览器功能 --> <item> <ID>11</ID> <type>1</type> <key>602</key> <cmd>am start -n com.android.browser/.BrowserActivity</cmd> </item> <!-- 计算器功能 --> <item> <ID>12</ID> <type>0</type> <key>506</key> <cmd>am start -n com.android.calculator2/.Calculator</cmd> </item> <!-- 图库功能 --> <item> <ID>13</ID> <type>0</type> <key>506</key> <cmd>am start -n com.android.gallery3d/.app.GalleryActivity</cmd> </item> <!-- 单屏功能 --> <item> <ID>14</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 多屏功能 --> <item> <ID>15</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 界面管理功能 --> <item> <ID>16</ID> <type>0</type> <key>506</key> <cmd>am start -n com.actions.arlauncher/.AllAppActivity</cmd> </item> <!-- 邮件 --> <item> <ID>17</ID> <type>0</type> <key>506</key> <cmd>am start -n com.android.email/.activity.Welcome</cmd> </item> <!-- 百事通 --> <item> <ID>18</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 微信 --> <item> <ID>19</ID> <type>0</type> <key>506</key> <cmd>am start -n com.tencent.mm/.ui.LauncherUI</cmd> </item> <!-- QQ --> <item> <ID>20</ID> <type>0</type> <key>506</key> <cmd>am start -n com.tencent.mobileqq/.activity.SplashActivity</cmd> </item> <!-- 花椒 --> <item> <ID>21</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 酷我音乐 --> <item> <ID>22</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 百度音乐 --> <item> <ID>23</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 百度地图 --> <item> <ID>24</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 高德导航 --> <item> <ID>25</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 取消关机 --> <item> <ID>26</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 确认关机 --> <item> <ID>27</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 确认待机 --> <item> <ID>28</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 取消待机 --> <item> <ID>29</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 拍摄一张照片 --> <item> <ID>30</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 开始摄像 --> <item> <ID>31</ID> <type>0</type> <key>506</key> <cmd>no</cmd> </item> <!-- 停止摄像 --> <item> <ID>32</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- wifi功能 --> <item> <ID>33</ID> <type>0</type> <key>506</key> <cmd>am start -n com.android.settings/.Settings\$WifiSettingsActivity</cmd> </item> <!-- 电池功能 --> <item> <ID>34</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 蓝牙功能打开 --> <item> <ID>35</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 蓝牙功能关闭 --> <item> <ID>36</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 显示功能 --> <item> <ID>37</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <!-- 返回,退出 --> <item> <ID>38</ID> <type>1</type> <key>506</key> <cmd>no</cmd> </item> <item> <ID>39</ID> <type>1</type> <key>502</key> <cmd>no</cmd> </item> </volbook>