XML解析

Dom解析

/**
 * Node
 * 数据类型基类
 * Element
 * 最常用的类
 * Attr
 * Element的属性
 * Text
 * Element or Attr的内容
 * Document
 * 代表整个XML文档,代表DOM tree
 */

public class DomXml {
    /**
     * <?xml version ="1.0" encoding="UTF-8"?>`
     * <code>
     * <language id="1">
     * <name>Java</name>
     * <usage>Android</usage>
     * </language>
     * <language id="2">
     * <name>Swift#</name>
     * <usage>iOS</usage>
     * </language>
     * <language id="3">
     * <name>Html5</name>
     * <usage>Web</usage>
     * </language>
     * </code>
     * @param context
     */
    public void domxml(Context context) {
        try {
            //得到 DocumentBuilderFactory 对象
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            //得到DocumentBuilder对象
            DocumentBuilder builder = factory.newDocumentBuilder();
            //打开xml文件到输入流
            InputStream stream = context.getAssets().open("subject.xml");
            //建立Document存放整个xml的Document对象数据
            Document parse = builder.parse(stream);
            //得到 XML数据的"根节点"
            Element element = parse.getDocumentElement();
            //获取根节点的所有language的节点
            NodeList list = element.getElementsByTagName("language");
            for (int i = 0; i < list.getLength(); i++) {
                //获取lan的所有子元素
                Element lan = (Element) list.item(i);
                String id = lan.getAttribute("id");
                String name = lan.getElementsByTagName("name").item(0).getTextContent();

            }

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        }
    }

}

Sax  解析

/**
 * Sax  解析
 * 
 */
public class SaxXml extends DefaultHandler {
    private List<HashMap<String, String>> list = null; //解析后的XML内容
    private HashMap<String, String> map = null;  //存放当前需要记录的节点的XML内容
    private String currentTag = null;//当前读取的XML节点
    private String currentValue = null;//当前节点的XML文本值
    private String nodeName = null;//需要解析的节点名称

    public SaxXml(String nodeName) {
        // 设置需要解析的节点名称
        this.nodeName = nodeName;
    }

    /**
     * 开始 XML 解析时调用
     * 初始化集合
     *
     * @throws SAXException
     */
    @Override
    public void startDocument() throws SAXException {
        // 接收文档开始的通知
        // 实例化ArrayList用于存放解析XML后的数据
        list = new ArrayList<HashMap<String, String>>();
    }

    /**
     * 开始解析某个节点时调用
     *
     * @param uri
     * @param localName
     * @param qName
     * @param attributes
     * @throws SAXException
     */
    @Override
    public void startElement(String uri, String localName, String qName,
                             Attributes attributes) throws SAXException {
        // 接收元素开始的通知
        if (qName.equals(nodeName)) {
            //如果当前运行的节点名称与设定需要读取的节点名称相同,则实例化HashMap
            map = new HashMap<String, String>();
        }
        //Attributes为当前节点的属性值,如果存在属性值,则属性值也读取。
        if (attributes != null && map != null) {
            for (int i = 0; i < attributes.getLength(); i++) {
                //读取到的属性值,插入到Map中。
                map.put(attributes.getQName(i), attributes.getValue(i));
            }
        }
        //记录当前节点的名称。
        currentTag = qName;
    }

    /**
     * 获取节点中的内容时调用
     *
     * @param ch
     * @param start
     * @param length
     * @throws SAXException
     */
    @Override
    public void characters(char[] ch, int start, int length)
            throws SAXException {
        // 接收元素中字符数据的通知。
        //当前节点有值的情况下才继续执行
        if (currentTag != null && map != null) {
            //获取当前节点的文本值,ch这个直接数组就是存放的文本值。
            currentValue = new String(ch, start, length);
            if (currentValue != null && !currentValue.equals("")
                    && !currentValue.equals("\n")) {
                //读取的文本需要判断不能为null、不能等于”“、不能等于”\n“
                map.put(currentTag, currentValue);
            }
        }
        //读取完成后,需要清空当前节点的标签值和所包含的文本值。
        currentTag = null;
        currentValue = null;
    }

    /**
     * 完成解析某个节点时调用
     *
     * @param uri
     * @param localName
     * @param qName
     * @throws SAXException
     */
    @Override
    public void endElement(String uri, String localName, String qName)
            throws SAXException {
        // 接收元素结束的通知。
        if (qName.equals(nodeName)) {
            //如果读取的结合节点是我们需要关注的节点,则把map加入到list中保存
            list.add(map);
            //使用之后清空map,开始新一轮的读取person。
            map = null;
        }
    }

    /**
     * 完成整个 XML 解析时调用
     *
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException {
        super.endDocument();
    }

    //方法:获取解析之后的数据
    public List<HashMap<String, String>> getList() {
        return list;
    }

    /**
     * 此方法在处理网络请求数据
     *
     * such as    :  http://10.0.2.2/get_data.xml
     * 使用okhttp 请求得的这个文件的   String xmlData = response.body().string();
     * 成功后的xmlData 可以拿来解析
     * xml 具体机构和你的业务有关系
     *
     * @param xmlData
     */
    private  static  void parseXMLWithSAX(String xmlData) {

        try {
            // 创建 SAXParserFactory 对象
            SAXParserFactory factory = SAXParserFactory.newInstance();
            // 获取 XMLReader 对象
            XMLReader xmlReader = factory.newSAXParser().getXMLReader();
            SaxXml handler = new SaxXml("name");
            // 将 ContentHandler 的实例设置到 XMLReader 中
            xmlReader.setContentHandler(handler);
            // 开始执行解析
            xmlReader.parse(new InputSource(new StringReader(xmlData)));

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

}

Pull 解析

/**
 * Pull 解析
 */
public class PullXml {
    /**
     * 此方法在处理网络请求数据
     *
     * such as    :  http://10.0.2.2/get_data.xml
     * 使用okhttp 请求得的这个文件的   String xmlData = response.body().string();
     * 成功后的xmlData 可以拿来解析
     * xml 具体机构和你的业务有关系
     *
     * @param xmlData
     */
    private static   void parseXMLWithPull(String xmlData) {
        try {
            // 1. 获取 XmlPullParserFactory 实例
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            // 2. 借助 XmlPullParserFactory 实例得到 XmlPullParser 对象
            XmlPullParser xmlPullParser = factory.newPullParser();
            // 3. 调用 setInput() 方法设置xml数据
            xmlPullParser.setInput(new StringReader(xmlData));
            // 4. 获取当前的解析事件
            int eventType = xmlPullParser.getEventType();
            String id = "";
            String name = "";
            String sex = "";
            // 5. 通过 while 循环不断地进行解析
            while (eventType != XmlPullParser.END_DOCUMENT) {
                String nodeName = xmlPullParser.getName();
                switch (eventType) {
                    // 开始解析某个节点
                    case XmlPullParser.START_TAG:
                        if ("id".equals(nodeName)) {
                            id = xmlPullParser.nextText();
                        } else if ("name".equals(nodeName)) {
                            name = xmlPullParser.nextText();
                        } else if ("sex".equals(nodeName)) {
                            sex = xmlPullParser.nextText();
                        }
                        break;
                    // 完成解析某个节点
                    case XmlPullParser.END_TAG:
                        if ("student".equals(nodeName)) {
                            Log.d("pull解析:", "id is" + id);
                            Log.d("pull解析:", "name is" + name);
                            Log.d("pull解析:", "sex is" + sex);
                        }
                        break;
                    default:
                        break;
                }
                // 获取下一个解析事件
                eventType = xmlPullParser.next();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
注意:
  • XML元素命名规则
  1. 不能以数字或标点符号开头
  2. 不能包含空格
  3. 不能以xml开头

解析方式:

  • 解析XML,即从XML中提取有用的信息
  • XML的解析方式主要分为2大类:


总结:


参考:https://www.jianshu.com/p/e636f4f8487b

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值