数据解析之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万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章