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>