Android之深入理解xml資料的pull解析

一個自學的程式設計師發表於2017-10-29

對於xml資料的解析方式我們應該重點掌握Pull方式的解析方法,如果你剛開始學習xml資料的解析方式或者掌握的不夠牢固,那麼來吧,我帶你深入理解掌握pull方式的解析方法!
首先你要清楚,pull解析是基於事件的解析,pull解析有如下幾個重要的解析事件
1. int START_DOCUMENT = 0;
2. int END_DOCUMENT = 1;
3. int START_TAG = 2;
4. int END_TAG = 3;

以上四個就是我認為pull解析中比較重要的四個解析事件及其在原始碼中的常量值。接下來簡單說明一下
1. START_DOCUMENT 開始解析文件
2. int END_DOCUMENT 結束解析文件
3. int START_TAG 開始解析標籤
4. END_TAG 結束解析標籤

對於學過的這當然沒什麼難的,但是如果剛入手可能不明白這都是什麼意思啊,不急,我們繼續。
接下來首先要說的是關於xml資料,既然我們是要解析xml資料的,所以我們需要有一個xml資料,我們這裡以解析本地xml資料為例,新建一個文字文件改名“data.xml”,在裡面書寫如下內容

<student>
    <student1>
        <name>張三</name>
        <age>25</age>
    </student1>

    <student1>
        <name>李四</name>
        <age>23</age>
    </student1>
</student>

以上就是一份xml資料了,接下來我們就對這份xml資料進行解析,另外這裡的解析指的是什麼呢?我們這裡說的解析是指拿到xml資料中的name和age的值。接下來我們在實際的程式碼中去展示如何一步步通過pull去解析xml資料的。
新建一個專案PullDemo,切換到Project下在main下新建一個資料夾命名assets,然後將我們建立的xml資料data.xml放到這個資料夾下。

準備工作完成之後我們開始一步步去解析xml資料,接下來我們主要在MainActivity中操作程式碼,首先我們使用pull去解析xml資料,所以肯定需要一個解析器,那麼我們就來建立一個解析器

 //1.獲得xml資料解析器
        XmlPullParser parser = Xml.newPullParser();

這行程式碼就成功建立了一個解析器parser,接下來很多地方都要用到他。有了解析器,下一步就是準備xml資料了,我們提前已經建立好了xml資料,現在的的問題是如何將資料與解析器關聯起來並開始解析呢?我們可以通過如下程式碼來完成

 //2.獲得資料
InputStream stream = this.getAssets().open("data.xml");
 //3.開始解析
parser.setInput(stream,"utf-8");

通過上述兩行程式碼我們就將xml資料與解析器關聯了起來並且開始解析了,接下來我們將解析的過程通過程式碼的方式一步步分解來讓你徹底明白xml資料是如何通過pull解析的,我們是如何得到我們想要的值的。

還記得開篇提到得解析事件嗎?在實際得解析過行程中我們就是通過判斷不同的解析事件去執行程式碼的,所以我們先要獲得解析事件。

//4.得到當前解析事件
            int event = parser.getEventType();

解析事件到底是什麼呢?不急我們通過程式碼驗證一下,看看這個event到底是什麼。

 //4.得到當前解析事件
            int event = parser.getEventType();
            System.out.println(event);
            10-29 15:32:50.524 28592-28592/com.ithuangqing.pulldemo I/System.out: 0

我這裡為了展示將輸出結果和程式碼放在一起了,我們發現這個event的值是0.還記得開篇說的這幾個常量值嗎!
1. int START_DOCUMENT = 0;
2. int END_DOCUMENT = 1;
3. int START_TAG = 2;
4. int END_TAG = 3;

沒錯,這裡的0就是指的START_DOCUMENT,這個常量表示的是開始解析文件,在接下來的操作中請你務必熟記這幾個常量值以及其代表的含義。另外說一點關於xml資料的問題,在xml資料中<>這樣的叫做開標籤,

 //得到標籤名字
            String codeName = parser.getName();

通過此方法我們就可以讀取到標籤的名字,接下來在程式碼中實際展示下。

//4.得到當前解析事件
            int event = parser.getEventType();
            System.out.println(event);
            //得到標籤名字
            String codeName = parser.getName();
            System.out.println(codeName);
10-29 15:45:14.261 8641-8641/com.ithuangqing.pulldemo I/System.out: 0
10-29 15:45:14.261 8641-8641/com.ithuangqing.pulldemo I/System.out: null

我們可以看到,當開始解析文件執行到事件0,此時還沒有開始讀取標籤,所以標籤的名字是null,此時事件停留在0,那麼我們如何執行下一個事件呢?可以通過如下程式碼將事件下移

 parser.next();

此時我們再來看看當前的事件是什麼

 //4.得到當前解析事件
            int event = parser.getEventType();
            System.out.println(event);
            //得到標籤名字
            String codeName = parser.getName();
            System.out.println(codeName);
            event = parser.next();
            System.out.println(event);
10-29 15:54:05.813 16924-16924/com.ithuangqing.pulldemo I/System.out: 0
10-29 15:54:05.813 16924-16924/com.ithuangqing.pulldemo I/System.out: null
10-29 15:54:05.813 16924-16924/com.ithuangqing.pulldemo I/System.out: 2

可以看到此時已經開始執行事件2了,還記得2代表什麼嗎?當事件執行到了2就代表開始解析標籤讀取開標籤的名字了,我們看我們的data.xml中第一個開標籤的名字是student,我們來獲取下此時的標籤名字看看是不是student。

event = parser.next();
            System.out.println(event);
            System.out.println(parser.getName());
10-29 15:57:54.573 20854-20854/com.ithuangqing.pulldemo I/System.out: 2
10-29 15:57:54.573 20854-20854/com.ithuangqing.pulldemo I/System.out: student

正如我們所看到的,此時讀取到的正是student,那麼pull的解析有什麼樣的規律呢?pull解析xml資料遵循從上到下從左到右,我們就xml資料來詳細說一下,先來看如下xml資料

<student>
    <student1>
        <name>張三</name>
        <age>25</age>
    </student1>

    <student1>
        <name>李四</name>
        <age>23</age>
    </student1>
</student>

當執行到0的時候代表開始解析文件,此時沒有標籤,所以標籤名字為空,接下來執行到事件2代表開始解析標籤,這個時候會解析這個開標籤,此時我們可以拿到標籤的名字student,當解析事件下移會開始解析到後面的屬性值,此時的事件是3(可以在XmlPullParser類中具體檢視),所以沒有標籤得到的標籤名同樣為空,緊接著執行到3,此時會解析屬性值後面的閉標籤,沒有的話同樣為空,再繼續就會重新回到事件2開始解析這個開標籤,也就是說,pull解析會按照<開標籤>屬性值<閉標籤>的順尋解析,並且是從上至下的,你可以在程式碼中寫上如下程式碼

//3.開始解析
            parser.setInput(stream,"utf-8");
            //4.得到當前解析事件
            int event = parser.getEventType();
            System.out.println(event);
            //得到標籤名字
            String codeName = parser.getName();
            System.out.println(codeName);
            event = parser.next();
            System.out.println(event);
            System.out.println(parser.getName());

            event = parser.next();
            System.out.println(event);
            System.out.println(parser.getName());

            event = parser.next();
            System.out.println(event);
            System.out.println(parser.getName());

            event = parser.next();
            System.out.println(event);
            System.out.println(parser.getName());

也就是多寫幾個下移事件,一步步的分解者去看其是如何解析的,輸出如下

10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 0
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: null
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 2
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: student
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 4
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: null
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 2
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: student1
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 4
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: null
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 2
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: name
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 4
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: null
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 3
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: name
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: 4
10-29 16:10:40.046 1482-1482/com.ithuangqing.pulldemo I/System.out: null

以上我們詳細介紹了pull是如何解析xml資料的,接下來我們來看看整體的程式碼

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
    public void click(View view){
        //1.獲得xml資料解析器
        XmlPullParser parser = Xml.newPullParser();
        //2.獲得資料
        try {
            InputStream stream = this.getAssets().open("data.xml");
            //3.開始解析
            parser.setInput(stream,"utf-8");
            //4.得到當前解析事件
            int event = parser.getEventType();

            String name = "";
            String  age = "";
            while (event != XmlPullParser.END_DOCUMENT){
                //5.得到標籤名字
                String nodeName = parser.getName();
             switch (event){
                 case XmlPullParser.START_TAG:{
                     if ("name".equals(nodeName)){
                         name = parser.nextText();
                     }else if ("age".equals(nodeName)){
                         age = parser.nextText();
                     }
                     break;
                 }
                 case XmlPullParser.END_TAG:{
                     if ("student1".equals(nodeName)){
                         System.out.println("名字是:"+name+"--"+"年齡是:"+age);
                     }
                     break;
                 }
                 default:
                     break;
             }
                //6.獲得下一個解析事件
               event =  parser.next();
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

輸出結果為

10-29 16:32:38.665 21804-21804/com.ithuangqing.pulldemo I/System.out: 名字是:張三--年齡是:25
10-29 16:32:38.665 21804-21804/com.ithuangqing.pulldemo I/System.out: 名字是:李四--年齡是:23

好了以上就是關於xml資料的pull解析了,由於本人入門不久且都是自學,若有不當之處望請見諒還希望多指教,如果能幫到你我很高興,謝謝!

相關文章