使用DOM解析XML

项目中经常需要和XML打交道,例如调用第三方接口的接口返回值、入参之类的,更多的是XML的解析。常用的XML解析方式有DOM、SAX等。

1、DOM和SAX是Java官方提供的解析XML的方式,不需要导入额外的包

2、本篇讲述如何利用DOM解析XML格式文件:

以下面的demo.xml为例

<?xml version="1.0" encoding="UTF-8"?>
<persons>
    <person id="person1" >
        <name>simons</name>
        <sex>男</sex>      
        <age>24</age>
        <address>魔都</address>
    </person>

    <person id="person2" >
       <name>rose</name>
        <sex>女</sex>      
        <age>22</age>
        <address>帝都</address>
    </person>
</persons>

相对应的DOM解析XML代码如下

import lombok.extern.slf4j.Slf4j;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.ByteArrayInputStream;

@Slf4j
public class DomResolveXml {
    public static void main(String[] args) {
        //创建DocumentBuilderFactory对象
        DocumentBuilderFactory db = DocumentBuilderFactory.newInstance();
        try {
            //创建DocumentBuilder对象
            DocumentBuilder documentBuilder = db.newDocumentBuilder();
            //加载本地文件
            // Document document = documentBuilder.parse(new File("D:/demo.xml"));
            StringBuffer buffer = new StringBuffer("<?xml version=\"1.0\" encoding=\"UTF-8\"?><persons><person id=\"person1\"><name>simons</name><sex>男</sex><age>24</age><address>魔都</address></person><person id=\"person2\" ><name>rose</name><sex>女</sex><age>22</age><address>帝都</address></person></persons>");
            //这里直接把xml内容加载为流,供Document加载
            ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(buffer.toString().getBytes("UTF-8"));
            Document document = documentBuilder.parse(byteArrayInputStream);
            //获取person节点
            NodeList beans = document.getElementsByTagName("person");
            log.info("一共有" + beans.getLength() + "个person节点");
            for (int i = 0; i < beans.getLength(); i++) {
                Node node = beans.item(i);
                NamedNodeMap attributes = node.getAttributes();
                //遍历person节点的属性名和属性值
                for (int j = 0; j < attributes.getLength(); j++) {
                    Node item1 = attributes.item(j);
                    //获取person节点下属性名
                    String nodeName = item1.getNodeName();
                    //获取person节点下属性值
                    String nodeValue = item1.getNodeValue();
                    log.info("属性名=" + nodeName + ",属性值=" + nodeValue);
                }
                //获取person节点下的子节点
                NodeList childNodes = node.getChildNodes();
                for (int j = 0; j < childNodes.getLength(); j++) {
                    String nodeName = childNodes.item(j).getNodeName();
                    //解析时候空格也会作为一个节点返回,这一点需要注意,查看下方的表格可知
                    if (childNodes.item(j).getNodeType() == Node.ELEMENT_NODE) {
                        //注:直接用childNodes.item(j).getNodeValue()获取到的为null
                        //注意:当 <name><a>www.baidu.com</a>simons</name>时候,区分这两个取值子节点value的方法区别
                        //  String nodeValue = childNodes.item(j).getFirstChild().getNodeValue();
                        String nodeValue = childNodes.item(j).getTextContent();
                        log.info("person节点下属性名=" + nodeName + ",属性值=" + nodeValue);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

节点类型

NodeType

Named Constant

getNodeName返回值

getNodeValue的返回值

Element

1

ELEMENT_NODE

element name

null

Attr

2

ATTRIBUTE_NODE

属性名

属性值

Text

3

TEXT_NODE

#text

节点内容

接着你需要做的就是处理解析出来的xml数据了。引申阅读:使用SAX解析XML。

猜你喜欢

转载自blog.csdn.net/fanrenxiang/article/details/81078854