數據解析之XML

數據解析之XML

什麼是 XML?

  • XML 指可擴展標記語言(EXtensible Markup Language)
  • XML 是一種標記語言,很類似 HTML
  • XML 的設計宗旨是傳輸數據,而非顯示數據
  • XML 標籤沒有被預定義。您需要自行定義標籤。
  • XML 被設計爲具有自我描述性。
  • XML 是 W3C 的推薦標準

示例

<?xml version="1.0" encoding="UTF-8" ?>
<peoples>
    <people>
        <name>張三</name>
        <age>23</age>
        <birthday>1994-01-01</birthday>
        <school>藍翔</school>
        <major>理髮</major>
        <major>挖掘機</major>
        <married>false</married>
        <car>大衆</car>
    </people>
    <people>
        <name>小紅</name>
        <age>20</age>
        <birthday>1996-01-01</birthday>
        <school>清華</school>
        <major>理髮</major>
        <major>化妝</major>
        <married>true</married>
        <car />
    </people>
</peoples>

常用的兩種XML解析方法

1.使用Pull的方式解析

實現步驟:

1.獲取XmlPullParserFactory實例
XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
2.藉助XmlPullParserFactory實例得到XmlPullParser對象,傳入XML數據
XmlPullParser xmlPullParser = factory.newPullParser();
//調用XmlPullParser的setInput()方法傳入XML數據
xmlPullParser.setInput(new StringReader(xmlData));
3.通過getEventType()獲得當前解析事件,在while循環中不斷解析,直到解析事件爲XmlPullParser.END_DOCUMENT,解析結束
int eventType = xmlPullParser.getEventType();
while (eventType != XmlPullParser.END_DOCUMENT) {
    ...
}

方法設計

/**
 * 使用Pull的方式解析
 *
 * @param xmlData XML數據
 */
public static void parseXmlWithPull(String xmlData) {
    try {
        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        XmlPullParser xmlPullParser = factory.newPullParser();
        xmlPullParser.setInput(new StringReader(xmlData));
        //獲取當前解析事件
        int eventType = xmlPullParser.getEventType();

        //解析時遇到的結點
        String name = "";
        int age = 0;
        String birthday = "";
        String school = "";
        String major = "";
        boolean married = false;
        String car = "";

        //直到解析事件爲XmlPullParser.END_DOCUMENT,解析結束
        while (eventType != XmlPullParser.END_DOCUMENT) {
            //當前結點名
            String nodeName = xmlPullParser.getName();
            switch (eventType) {
                //開始解析某個節點
                case XmlPullParser.START_TAG: {
                    try {
                        if ("name".equals(nodeName)) {
                            //nextText()獲取節點內具體內容
                            name = xmlPullParser.nextText();
                        } else if ("age".equals(nodeName)) {
                            age = Integer.parseInt(xmlPullParser.nextText());
                        } else if ("birthday".equals(nodeName)) {
                            birthday = xmlPullParser.nextText();
                        } else if ("school".equals(nodeName)) {
                            school = xmlPullParser.nextText();
                        } else if ("major".equals(nodeName)) {
                            major = xmlPullParser.nextText();
                        } else if ("married".equals(nodeName)) {
                            married = Boolean.parseBoolean(xmlPullParser.nextText());
                        } else if ("car".equals(nodeName)) {
                            car = xmlPullParser.nextText();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    break;
                }
                case XmlPullParser.END_TAG: {
                    if ("people".equals(nodeName)) {
                        Log.d(TAG, "parseXmlWithPull: name= " + name + "\nage= " + age +
                                "\nbirthday= " + birthday + "\nschool= " + school +
                                "\nmajor= [" + major + "]\nmarried= " + married +
                                "\ncar= " + car);
                    }
                    break;
                }
                default:
                    break;
            }
            try {
                eventType = xmlPullParser.next();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    } catch (XmlPullParserException e) {
        e.printStackTrace();
    }
}

2.使用SAX的方式解析XML

解析步驟

1.創建SAXParserFactory對象
SAXParserFactory factory = SAXParserFactory.newInstance();
2.通過SAXParserFactory對象獲取XMLReader
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
3.將自定義的ContentHandler實例設置到XMLReader中,調用parse()方法,傳入XML數據開始解析
ContentHandler handler = new ContentHandler();
//將ContentHandler對象設置到XMLReader中
xmlReader.setContentHandler(handler);
//開始執行解析
xmlReader.parse(new InputSource(new StringReader(xmlData)));

/**
 * 使用SAX的方式解析XML
 *
 * @param xmlData
 */
public static void parseXmlWithSAX(String xmlData) {
    try {
        SAXParserFactory factory = SAXParserFactory.newInstance();
        XMLReader xmlReader = factory.newSAXParser().getXMLReader();
        ContentHandler handler = new ContentHandler();
        //將ContentHandler對象設置到XMLReader中
        xmlReader.setContentHandler(handler);
        //開始執行解析
        xmlReader.parse(new InputSource(new StringReader(xmlData)));
    } catch (SAXException e) {
        e.printStackTrace();
    } catch (ParserConfigurationException e) {
        e.printStackTrace();
    } catch (IOException e) {
        e.printStackTrace();
    }

}

/**
 * SAX解析輔助類
 */
private static class ContentHandler extends DefaultHandler {
    private String nodeName;

    private StringBuilder name;
    private StringBuilder age;
    private StringBuilder birthday;
    private StringBuilder school;
    private StringBuilder major;
    private StringBuilder married;
    private StringBuilder car;

    /**
     * 開始XML解析時調用
     *
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        name = new StringBuilder();
        age = new StringBuilder();
        birthday = new StringBuilder();
        school = new StringBuilder();
        major = new StringBuilder();
        married = new StringBuilder();
        car = new StringBuilder();
    }

    /**
     * 開始解析某個節點時調用
     *
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        //記錄當前節點名
        nodeName = localName;
    }

    /**
     * 獲取節點的內容時調用
     *
     * @param ch
     * @param start
     * @param length
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        //根據當前的節點名判斷將內容添加到哪個StringBuilder對象中
        if ("name".equals(nodeName)) {
            name.append(ch, start, length);
        } else if ("age".equals(nodeName)) {
            age.append(ch, start, length);
        } else if ("birthday".equals(nodeName)) {
            birthday.append(ch, start, length);
        } else if ("school".equals(nodeName)) {
            school.append(ch, start, length);
        } else if ("major".equals(nodeName)) {
            major.append(ch, start, length);
        } else if ("married".equals(nodeName)) {
            married.append(ch, start, length);
        } else if ("car".equals(nodeName)) {
            car.append(ch, start, length);
        }
    }

    /**
     * 完成解析某個節點時調用
     *
     * @param uri
     * @param localName
     * @param qName
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if ("people".equals(localName)) {
            Log.d(TAG, "endElement: \n" +
                    "name= " + name + "\nage= " + age + "\nbirthday= " + birthday + "\nschool= " + school + "\nmajor= " +
                    major + "\nmarrid= " + married + "\ncar= " + car);
            //最後將StringBuilder清空
            name.setLength(0);
            age.setLength(0);
            birthday.setLength(0);
            school.setLength(0);
            major.setLength(0);
            married.setLength(0);
            car.setLength(0);
        }
    }

    /**
     * 完成整個XML解析時調用
     *
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
    }
}
發佈了36 篇原創文章 · 獲贊 20 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章