天天看點

第10天xml解析

第10天xml解析

    • 一.xml介紹:
    • 二.Xml解析:
      • 1.PULL
      • 2.SAX
      • 3.DOM
      • 4.SAX、DOM、Pull三種解析方式的比較
    • 三 .下面分别采用3種方式進行解析xml檔案
      • 1.Pull解析
      • 2.DOM解析
    • 五.SAX解析

一.xml介紹:

1.XML:Extensible Markup Language,即可擴充标記語言. 用于标記電子檔案使其具有結構性的标記語言,可以用來标記資料、定義資料類型,是一種允許使用者對自己的标記語言進行定義的源語言。非常适合 Web 傳輸。XML 提供統一的方法來描述和交換獨立于應用程式或供應商的結構化資料.

舉例如下:

<?xml version="1.0" encoding="utf-8" ?>
<country>
  <name>中國</name>
  <province>
    <name>黑龍江</name>
    <citys>
      <city>哈爾濱</city>
      <city>大慶</city>
    </citys>    
  </province>
  <province>
</country>

           
第10天xml解析

2.XML和Json都可以在網絡傳輸中使用的。現在主要是使用Json傳輸.

Json:

{
         name: "中國",
         provinces: [
         { name: "黑龍江", citys: { city: ["哈爾濱", "大慶"]} },
         { name: "廣東", citys: { city: ["廣州", "深圳", "珠海"]} },
         { name: "台灣", citys: { city: ["台北", "高雄"]} },
         { name: "新疆", citys: { city: ["烏魯木齊"]} }
         ]
}
           
  1. 兩者比較:

    A,可讀性來說,XML有明顯的優勢,畢竟人類的語言更貼近這樣的說明結構。JSON讀起來更像一個資料塊,但讀起來就比較費解了。

    B,傳輸效率上來說,JSON更為清晰且備援更少些。JSON網站提供了對JSON文法的嚴格描述,隻是描述較簡短。

    從總體來看,XML比較适合于标記文檔(配置工程),而JSON卻更适于進行資料交換的處理。

    C,編碼難度XML有豐富的編碼工具,比如Dom4j、JDom等,JSON也有json.org提供的工具,但是JSON的編碼明顯比XML容易許多,即使不借助工具也能寫出JSON的代碼,可是要寫好XML就不太容易了。

//1.獲得用戶端Socket
BluetoothSocket socket = bluetoothDevice.createRfcommSocketToServiceRecord(uuid);
socket.connect();
//2.獲得服務端Socket
BluetoothServerSocket serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(bluetoothAdapter.getName(),uuid);
serverSocket.accpet();
           

二.Xml解析:

1.PULL

Pull 内置于 Android 系統中。也是官方解析布局檔案所使用的方式。Pull 與 SAX 有點類似,都提供了類似的事件,如開始元素和結束元素。

不同的是,SAX 的事件驅動是回調相應方法,需要提供回調的方法,而後在 SAX 内部自動調用相應的方法。

而Pull解析器并沒有強制要求提供觸發的方法。因為他觸發的事件不是一個方法,而是一個數字。它使用友善,效率高。

2.SAX

SAX(Simple API for XML) 使用流式處理的方式,它并不記錄所讀内容的相關資訊。它是一種以事件為驅動的XML API,解析速度快,占用記憶體少。使用回調函數來實作。缺點是不能倒退。

3.DOM

DOM(Document Object Model) 是一種用于XML文檔的對象模型,可用于直接通路 XML 文檔的各個部分。它是一次性全部将内容加載在記憶體中,生成一個樹狀結構,它沒有涉及回調和複雜的狀态管理。

缺點是加載大文檔時效率低下。

4.SAX、DOM、Pull三種解析方式的比較

  • 記憶體占用:SAX、Pull比DOM要好;
  • 程式設計方式:SAX 采用事件驅動,在相應事件觸發的時候,會調用使用者編好的方法,也即每解析一類 XML,就要編寫一個新的适合該類XML的處理類。DOM 是 W3C 的規範,Pull 簡潔。
  • 通路與修改:SAX 采用流式解析,DOM 随機通路。
  • 通路方式:SAX,Pull 解析的方式是同步的,DOM 逐字逐句。

三 .下面分别采用3種方式進行解析xml檔案

<students>
    <student>
    <name sex="man" age="15">小明</name>
    <nickName>明明</nickName>
    </student>
    <student>
        <name sex="woman" age="16">小紅</name>
        <nickName>紅紅</nickName>
    </student>
    <student>
        <name sex="man" age="16">小亮</name>
        <nickName>亮亮</nickName>
    </student>
</students>
           

1.Pull解析

/**
 * 一。5種事件類型
 * XmlPullParser.START_DOCUMENT:文檔的開始
 * XmlPullParser.END_DOCUMENT:文檔的結束
 * XmlPullParser.START_TAG:開始标簽
 * XmlPullParser.END_TAG:結束标簽
 * XmlPullParser.TEXT:内容
 *二。重要的方法:
 * 1。XmlPullParser:getEventType()獲得目前事件類型
 * 2。XmlPullParser:getAttributeValue()獲得該标簽的屬性值
 * 3。XmlPullParser:next()向下移動一個
 * 4。XmlPullParser:nextText()向下移動一個并獲得文本内容
 * */
public class PullUtils {

    public static List<StudentBean>PullList(InputStream inputStream) throws XmlPullParserException, IOException {
        List<StudentBean>list = new ArrayList<>();
        //TODO 1:pull解析器工廠
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        //TODO 2:擷取pull解析器
        XmlPullParser parser = factory.newPullParser();
        //TODO 3:設定要解析的資料
        parser.setInput(inputStream,"utf-8");
        //TODO 4:獲得目前類型
        int type = parser.getEventType();
        StudentBean bean = null;
        //标簽類型不為文檔結束
        while (type!=XmlPullParser.END_DOCUMENT){
            switch (type){
                case XmlPullParser.START_TAG:
                    //标簽開始
                    if (parser.getName().equals("student")){
                        bean = new StudentBean();
                    }else if (parser.getName().equals("name")){
                        bean.sex = parser.getAttributeValue(0);
                        bean.age = parser.getAttributeValue(1);
                        bean.name = parser.nextText();
                    }else if (parser.getName().equals("nickName")){
                        bean.nickName = parser.nextText();
                    }
                    break;
                case XmlPullParser.END_TAG:
                    //标簽結束
                    if (parser.getName().equals("student"))
                        list.add(bean);
                    break;
            }
            type = parser.next();//向下讀取
        }
        return list;
    }
}
           

2.DOM解析

第10天xml解析
/**
 * 一。重要的方法:
 * 1。Document:getElementsByTagName(節點名稱):根據節點名稱獲得節點清單
 * 2。Node:getChildNodes():獲得目前節點所有的子節點
 * 3。Node:getAttributes():擷取目前節點所有的屬性和值
 * 4。Node:getNodeValue():獲得目前自節點的值
 * 5。Node:getTextContent():獲得目前節點的文本
 * 6。Node:getNodeName():獲得目前節點的名稱
 * */
public class DomUtils {

    public static List<StudentBean>DomList(InputStream in) throws ParserConfigurationException, IOException, SAXException {
        List<StudentBean>list = new ArrayList<>();
        //TODO 1:擷取dom解析器工廠
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        //TODO 2:擷取解析器
        DocumentBuilder builder = factory.newDocumentBuilder();
        //TODO 3:設定要解析的資料
        Document document = builder.parse(in);
        //TODO 4:獲得所有的student節點集合
        NodeList nodeList = document.getElementsByTagName("student");
        //TODO 5:周遊集合
        for (int i = 0;i < nodeList.getLength();i ++){
            Node node = nodeList.item(i);//對應student标簽
            StudentBean bean = new StudentBean();
            //周遊student标簽下子标簽
            NodeList childList = node.getChildNodes();
            for (int j = 0;j < childList.getLength();j ++){
                Node child = childList.item(j);//name标簽;nickname标簽
                //擷取name标簽下的屬性以及值
                if (child.getNodeName().equals("name")){
                    //擷取屬性sex以及age值
                    NamedNodeMap map = child.getAttributes();
                    Node sex = map.getNamedItem("sex");
                    Node age = map.getNamedItem("age");
                    bean.sex = sex.getNodeValue();
                    bean.age = age.getNodeValue();
                    bean.name = child.getTextContent();
                }else if (child.getNodeName().equals("nickName")){
                   //擷取nickname标簽下的值
                    bean.nickName = child.getTextContent();
                }
            }
            list.add(bean);
        }
        return list;
    }

}

           

五.SAX解析

第10天xml解析
public class SaxUtils {

    private List<StudentBean>list = new ArrayList<>();

    public List<StudentBean>SaxList(InputStream inputStream) throws IOException, ParserConfigurationException, SAXException {
        //TODO 1:擷取解析器工廠
        SAXParserFactory factory = SAXParserFactory.newInstance();
        //TODO 2:擷取解析器
        SAXParser parser = factory.newSAXParser();
        //TODO 3:綁定位元組流與解析器工具類->按照标簽位置解析xml
        parser.parse(inputStream,new SaxHelp());
       return list;
    }

    //建立内部類解析器->xml解析
    class SaxHelp extends DefaultHandler{
        String buff;
        StudentBean bean;
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            //文檔開始
        }

        @Override
        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
            super.startElement(uri, localName, qName, attributes);
            if (qName.equals("student")){
                bean = new StudentBean();
            }else if (qName.equals("name")){
                //擷取sax以及age屬性值
                bean.sex = attributes.getValue("sex");
                bean.age = attributes.getValue("age");
            }
        }

        @Override
        public void endElement(String uri, String localName, String qName) throws SAXException {
            super.endElement(uri, localName, qName);
            if (qName.equals("name")){
                bean.name = buff;
            }else if (qName.equals("nickName")){
                bean.nickName = buff;
            }else if (qName.equals("student")){
                list.add(bean);
            }
        }

        @Override
        public void characters(char[] ch, int start, int length) throws SAXException {
            super.characters(ch, start, length);//讀取标簽内容
            buff = new String(ch,start,length);//标簽内容char數組轉化為String字元串buff
            //在endElement 指派給bean.name或bean.nickname
        }

        @Override
        public void endDocument() throws SAXException {
            super.endDocument();
            //文檔結束
        }
    }

}