Android中基于XmlPullParser和DocumentBuilderFactory的XML解析 记录

XmlPullParser(Java版)

以下是XmlPullParser解析XML文件的常见方法及说明:

1. XmlPullParserFactory.newInstance():创建XmlPullParserFactory实例。

2. XmlPullParserFactory.setNamespaceAware(boolean):设置是否支持XML命名空间。

3. XmlPullParserFactory.setValidating(boolean):设置是否支持DTD验证。

4. XmlPullParserFactory.newPullParser():创建XmlPullParser实例。

5. XmlPullParser.setInput(InputStream, String):设置要解析的XML文件的输入流和编码方式。

6. XmlPullParser.getEventType():获取当前解析器的事件类型。

7. XmlPullParser.getName():获取当前节点的名称。

8. XmlPullParser.getText():获取当前节点的文本内容。

9. XmlPullParser.next():移动到下一个节点。

10. XmlPullParser.nextTag():移动到下一个标签节点。

11. XmlPullParser.getAttributeCount():获取当前节点的属性数量。

12. XmlPullParser.getAttributeName(int):获取当前节点指定位置的属性名称。

13. XmlPullParser.getAttributeValue(int):获取当前节点指定位置的属性值。

14. XmlPullParser.getDepth():获取当前节点的深度。

15. XmlPullParser.END_DOCUMENT:表示已经到达XML文件的末尾。

16. XmlPullParser.START_TAG:表示当前节点是一个标签节点。

17. XmlPullParser.END_TAG:表示当前节点是一个结束标签节点。

解析顺序: 开始的标签事件 ----> 文本事件 ----> 然后结束的标签事件

例如:

<?xml version="1.0" encoding="utf-8"?>
<keys>
    <board id="xml1">1
        <source>android 01</source>2
        <source>android 02</source>2
        <source>android 03</source>2
    </board>
    <board id="xml2">1
        <source>ios 01</source>3
        <source>ios 02</source>3
        <source>ios 05</source>3
    </board>4
</keys>

解析代码:

    private void parseData(){
    
    

        try {
    
    
            XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
            XmlPullParser parser = factory.newPullParser();
            InputStream inputStream = getAssets().open("text.xml");
            parser.setInput(inputStream,"utf-8");
            int eventType = parser.getEventType();
            String board = "";
            while (eventType != XmlPullParser.END_DOCUMENT){
    
    
                switch (eventType) {
    
    
                    case XmlPullParser.TEXT:
                        Log.d(TAG, "parseData: text  " + parser.getName() + "       " + parser.getText());
                        break;
                    case XmlPullParser.START_TAG:
                        String keys = parser.getName();
                        Log.d(TAG, "parseData: start -----" + parser.getName());
                        if (keys.equals("board")) {
    
    
                            board = parser.getAttributeValue(null, "id");
                        }
                        if (board.equals("xml1")) {
    
    
                            if (keys.equals("source")) {
    
    
//                                String result = parser.getText();
//                                Log.d(TAG, "initData: result = " + result);
//                                parser.next(); // 移动解析器到下一个事件,即 TEXT 事件
//                                String result = parser.getText();
//                                Log.d(TAG, "initData: result = " + result);
                            }
                        }
                        break;
                    case XmlPullParser.END_TAG:
                        Log.d(TAG, "initData: end -------" + parser.getName());
                        break;
                }
                eventType = parser.next();

            }

        } catch (IOException | XmlPullParserException e) {
    
    
            throw new RuntimeException(e);
        }

    }

运行结果:

2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: start -----keys
2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       
                                                                                                        
2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: start -----board
2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       1
                                                                                                            
2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.553 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       android 01
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       2
                                                                                                            
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       android 02
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       2
                                                                                                            
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       android 03
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       2
                                                                                                        
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  initData: end -------board
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       
                                                                                                        
2023-06-06 14:35:41.554 22162-22162 MainActivity            com.example.third                    D  parseData: start -----board
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       1
                                                                                                            
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       ios 01
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       3
                                                                                                            
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       ios 02
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       3
                                                                                                            
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: start -----source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       ios 05
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  initData: end -------source
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       3
                                                                                                        
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  initData: end -------board
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  parseData: text  null       4
2023-06-06 14:35:41.555 22162-22162 MainActivity            com.example.third                    D  initData: end -------keys

DocumentBuilderFactory(kotlin版)

以下是org.w3c.dom.Node的常见方法及使用说明:

1. getNodeName():获取节点的名称。

2. getNodeValue():获取节点的值。

3. getNodeType():获取节点的类型,返回一个整数值,具体取值如下:

- ELEMENT_NODE(1):元素节点
- ATTRIBUTE_NODE(2):属性节点
- TEXT_NODE(3):文本节点
- CDATA_SECTION_NODE(4):CDATA节点
- ENTITY_REFERENCE_NODE(5):实体引用节点
- ENTITY_NODE(6):实体节点
- PROCESSING_INSTRUCTION_NODE(7):处理指令节点
- COMMENT_NODE(8):注释节点
- DOCUMENT_NODE(9):文档节点
- DOCUMENT_TYPE_NODE(10):文档类型节点
- DOCUMENT_FRAGMENT_NODE(11):文档片段节点
- NOTATION_NODE(12):符号节点

4. getChildNodes():获取节点的子节点列表,返回一个NodeList对象。

  1. getParentNode():获取节点的父节点,返回一个Node对象。

  2. getAttributes():获取节点的属性列表,返回一个NamedNodeMap对象。

  3. hasChildNodes():判断节点是否有子节点,返回一个布尔值。

  4. getTextContent():获取节点的文本内容,返回一个字符串。

  5. getFirstChild():获取节点的第一个子节点,返回一个Node对象。

  6. getLastChild():获取节点的最后一个子节点,返回一个Node对象。

  7. getNextSibling():获取节点的下一个兄弟节点,返回一个Node对象。

  8. getPreviousSibling():获取节点的上一个兄弟节点,返回一个Node对象。

测试用例所使用xml:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <!--我是注释,也能被解析出来-->
    <A>Apple</A>
    我是A和B中间的文本
    <B>Banana</B>
    <C>我是C文本
        <D>Dog</D>我是D和E之间的文本
        <E>elephant</E>
    </C>我是C和F之间的文本
    <F>foot</F>我是F和G之间的文本
    <G>god</G>
</config>

测试用例代码:

fun main() {
    
    
    try {
    
    
        val factory = DocumentBuilderFactory.newInstance()
        val builder = factory.newDocumentBuilder()
        val file = File("D:\\DevSpace\\IDEA\\Project\\GUIProject\\src\\kotlinLearning\\config.xml")
        if(file.exists()){
    
    
            val stream = file.inputStream()
            val document = builder.parse(stream)
            val rootElement = document.documentElement
            println("${
      
      rootElement.tagName}   ${
      
      rootElement.nodeName}  ${
      
      rootElement.nodeValue}")
            println("============================================================================")
            val nodeList = rootElement.childNodes
            for(i in 0 until nodeList.length){
    
    
                val configNode : Node = nodeList.item(i)
                //单独判断C,有子标签的
                if(configNode.nodeName == "C"){
    
    
                    val element =  configNode as Element
                    println("tagName: ${
      
      element.tagName}  节点name: ${
      
      element.nodeName}  节点值: ${
      
      element.nodeValue} ")
                    val childNodes = element.childNodes
                    for (j in 0 until childNodes.length){
    
    
                        val child = childNodes.item(j)
                        if(child.nodeType == Element.ELEMENT_NODE){
    
    
                            val firstChild = child.firstChild
                            val nodeValue = firstChild.nodeValue
                            val nodeName = firstChild.nodeName
                            println("launcherInfo子节点的名为:$nodeName   值为:$nodeValue")
                        }

                    }
                }else{
    
    
                    println("Node的类型为: ${
      
      configNode.nodeType}   Node的名字为: ${
      
      configNode.nodeName}  Node的值为: ${
      
      configNode.nodeValue}   Node的子值为: ${
      
      configNode.firstChild?.nodeValue}")
                }
            }
        }else{
    
    
            println(file.absoluteFile)
            println("文件不存在")
        }
    }catch (e:Exception){
    
    
        e.stackTrace
    }

}

运行结果:

config   config  null
============================================================================
Node的类型为: 3   Node的名字为: #text  Node的值为: 
       Node的子值为: null
Node的类型为: 8   Node的名字为: #comment  Node的值为: 我是注释,也能被解析出来   Node的子值为: null
Node的类型为: 3   Node的名字为: #text  Node的值为: 
       Node的子值为: null
Node的类型为: 1   Node的名字为: A  Node的值为: null   Node的子值为: Apple
Node的类型为: 3   Node的名字为: #text  Node的值为: 
    我是A和B中间的文本
       Node的子值为: null
Node的类型为: 1   Node的名字为: B  Node的值为: null   Node的子值为: Banana
Node的类型为: 3   Node的名字为: #text  Node的值为: 
       Node的子值为: null
tagName: C  节点name: C  节点值: null 
launcherInfo子节点的名为:#text   值为:Dog
launcherInfo子节点的名为:#text   值为:elephant
Node的类型为: 3   Node的名字为: #text  Node的值为: 我是C和F之间的文本
       Node的子值为: null
Node的类型为: 1   Node的名字为: F  Node的值为: null   Node的子值为: foot
Node的类型为: 3   Node的名字为: #text  Node的值为: 我是F和G之间的文本
       Node的子值为: null
Node的类型为: 1   Node的名字为: G  Node的值为: null   Node的子值为: god
Node的类型为: 3   Node的名字为: #text  Node的值为: 
   Node的子值为: null

解析说明:(把例子拷贝一下跑一遍,对照着xml文件以及上面的函数解析,就可以理解了)

1. 标签中有值的话需要拿该标签中间的value不能直接getValue而是需要获取它的第一个子节点(也可以理解成标签)的value, 这个value就是我们要拿到的value(可以结合上述例子理解,具体解析原理我没看源码也不太清楚)

猜你喜欢

转载自blog.csdn.net/XJ200012/article/details/131288197