【XML解析】(1)Java下使用JAXP中的DOM解析方式对XML文档进行解析

关于JAXP、DOM、SAX:

何为JAXP?

JAXP(JavaApi for Xml Programming) – sun公司的一套操作XML的API。

JAXP中分为三种解析方式:

DOM解析、SAX解析、StAX

DOM解析:一次性的将数据全部装入内存。

SAX解析:边读取边解析。

DOM、SAX、StAX关键词解释:

【DOM】:

DOM-Document Object Model-文档对像模型。是w3c组织处理xml的一种方式。

DOM的特点:

①一次将所有数据全部加载到内存中。

②对xml文档中的每一个节点都当成一个Node对像处理。包括元素、文本、属性。

③org.w3c.dom包中的Document,Element,Node。

④非常方便进行修改。

⑤已经集成在了JDK中,是Sun对xml操作的标准。

⑥缺点是当文档数据量很大时,对内存有占用很大。

【SAX】:

Sax – Simple Api for XML 。

①在读取数据时分析数据,通过事件监听器来完成。

②速度快但只适合读取数据,仅向前读取不可后退。

【StAX】:

①The Streaming API for XML基于流的XML编程接口

②StAX即可读文档也可以写文档。

③而SAX只可以读取文档。

XML解析的方式分为以下几种-图解:

这里写图片描述

DOM解析的说明:

DOM解析一次将所有的元素全部加载到内存中:如有以下XML文档(users.xml):

users.xml:

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user id="A001">
        <name>Jack</name>
        <age>22</age>
    </user>
    <user id="A002">
        <name>张三</name>
        <age>21</age>
    </user>
</users>

【注意】由于DOM解析,一次性的将所有元素(包含属性和文本) 全部加载到内存中,所以不适用于解析大量的数据。

user.xml在内存中的DOM结构:

这里写图片描述

JAXP-DOM解析时候用到的Java包:

【org.w3c.dom】 – 关键类Document代表内存中的文档对像模型。

这里写图片描述
w3c是制定标准,具体的实现还是看sun公javax.xml.parsers

【javax.xml.parse】– 关键类DocumentBuilder,文档解析对像。

【javax.xml】– 关键类Transformer,用于将内存中的文档保存到文件中。

以上三个类之间的关系:

这里写图片描述

在DOM中,所有元素都是Node的子类:

这里写图片描述

DOM解析的具体实现方式:

准备XML数据:

users.xml 这里写图片描述

<?xml version="1.0" encoding="UTF-8"?>
<users>
    <user id="A001">
        <name>Jack</name>
        <age>22</age>
    </user>
    <user id="A002">
        <name>张三</name>
        <age>21</age>
    </user>
</users>

创建Document对象的思路:

①首先直接找到Document类,在org.w3c.dom包中找到,我们可以看到Document是一个接口,因此需要找到此接口的具体实现类或者能够返回出此类型的方法。

②因为w3c只是制定标准,具体类实现在sun公司的java包中,javax.xml.parsers。

③类 DocumentBuilderFactory构造方法是protected的,因此要找其中的static方法(newInstance() ),此方法返回此类类型,此时有了dbf对象。

④通过此对象dbf调用(newDocumentBuilder())得到DocumentBuilder类对象db。

⑤有了db对象,就可以调用此类(DocumentBuilder)中的parse(File f)方法就可以返回(Document)类对象dom。

创建Document对象代码实现:

第一步:创建工厂
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
第二步:创建解析器
DocumentBuilder db=dbf.newDocumentBuilder();
第三步:获得dom对象
Document dom=db.parse("./xml/users.xml");
第四步:通过节点(Node)或者元素(Element)方式解析DOM树
/....../

(一)通过节点(Node)方法解析DOM树:

第四步:首先获取根节点
Node rootNode=dom.getFirstChild();
第五步:接着获取此根节点的所有孩子节点
NodeList nodeList=rootNode.getChildNodes();
第六步:获取<user>标签的这个节点
Node userNode=nodeList.item(1);
第七步:获取<user>节点下的<name>节点
Node nameNode=userNode.getChildNodes().item(1)
第八步:获取此name节点的文本内容
String name=nameNode.getTextContent();

(二)通过Document中的getElementsByTagName()方法解析DOM树:

第四步:首先获取根节点:
Node root=dom.getFirstChild();
第五步:将根节点强转成Element元素类型
Element eroot=(Element) root;
第六步:通过标签名获取所有的此标签节点
NodeList userList=eroot.getElementsByTagName("user");
第七步:将某一个标签节点进行强转
Element eUser1=(Element) userList.item(0);
第八步:再逐层通过标签名获得某个元素
NodeList nameList=eUser1.getElementsByTagName("name");
Node nameNode=nameList.item(0);
String name=nameNode.getTextContent();

读取节点中的属性:

因为Node没有获取属性的方式,所以必须将Node强制向下转换成Element来处理。

使用:getAttribute(String name)来获取。
这里写图片描述

获取节点属性代码实现:

DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
DocumentBuilder db=dbf.newDocumentBuilder();
Document dom=db.parse("./xml/users.xml/");
//将根节点强制转换为元素类型
Node root=dom.getFirstChild();
Element eroot=(Element) root;
NodeList userList=eroot.getElementsByTagName("user");
Element eUser1=(Element) userList.item(0);
//获取user节点中的属性id
String id=eUser1.getAttribute("id");
System.out.println("id="+id);

完整代码演示:

package cn.hncu.jaxp.dom;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * 解析XML:
 * 1、解析XML的方式:JAXP(DOM、StAX)、jDom(dom4j)
 * 2、如何使用?
 * JDK中有两个专用于dom编程的包:
 * (1)、org.w3c.dom -----w3c是制定标准,具体的实现还是看sun公司的javax.xml.parsers
 * (2)、javax.xml.parsers -----sun公司具有开发出来解析的工具
 * 
 * 
 * 入口方式:
 * Document(来自org.w3c.dom)-->要用工厂方法获得该dom对象-->工厂方法来自sun公司(javax.xml.parsers)
 * 
 * 
 */

public class DomDemo {
    /*
     * 获取dom对象
     */
    @Test
    public void getDom() throws Exception{

        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document dom=db.parse("./xml/users.xml");
        System.out.println(dom);//[#document: null]
    }

    /*
     * 通过节点的方式获得name,age
     */
    @Test
    public void getName() throws Exception{
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document dom=db.parse("./xml/users.xml");
        //获得根节点
        Node rootNode=dom.getFirstChild();
        String rootNodeName=rootNode.getNodeName();
        System.out.println("rootNodeName= "+rootNodeName);  
        /*
         * 获得根节点的所有孩子节点:包括空白符和标签
         * 【注意】:
         *  1、通过Node中的getChildNodes(),返回类型为NodeList,获取当前节点的所有子节点(包括文本内容和标签节点)。
         *  2、但是一般不选择这种方式的理由:文本内容尤其是空白符也是其中的孩子节点,会产生干扰!
         *  3、因此最好的方式就是:通过Element下的getElementByTagName(String name)
         */
        NodeList nodeList=rootNode.getChildNodes();
        for(int i=0;i<nodeList.getLength();i++){
            System.out.println( nodeList.item(i).getNodeName());
        }
        //获取第一个user节点下的name、age
        Node userNode=nodeList.item(1);
        String name=userNode.getChildNodes().item(1).getTextContent();
        String age=userNode.getChildNodes().item(3).getTextContent();
        System.out.println(name+","+age);
        //获取第二个user节点下的name、age
        Node userNode2=nodeList.item(3);
        String name2=userNode2.getChildNodes().item(1).getTextContent();
        String age2=userNode2.getChildNodes().item(3).getTextContent();
        System.out.println(name2+","+age2);
    }

    /*
     * 建议采用的方式:用Element中的getElementsByTagName(String name)
     * 为了使用使用Element中的方法必须将Node强转成Element类型。 
     */
    @Test
    public void getName2() throws Exception{
        DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
        DocumentBuilder db=dbf.newDocumentBuilder();
        Document dom=db.parse("./xml/users.xml/");
        //将根节点强制转换为元素类型
        Node root=dom.getFirstChild();
        Element eroot=(Element) root;
        NodeList userList=eroot.getElementsByTagName("user");
        Element eUser1=(Element) userList.item(0);
        //获取user节点中的属性id
        String id=eUser1.getAttribute("id");
        System.out.println("id="+id);

        //获取name
        NodeList nameList=eUser1.getElementsByTagName("name");
        Node nameNode=nameList.item(0);
        String name=nameNode.getTextContent();
        //获取age
        NodeList ageList=eUser1.getElementsByTagName("age");
        Node ageNode=ageList.item(0);
        String age=ageNode.getTextContent();
        System.out.println(name+":"+age);

    }


}

运行结果:

getName()运行结果:

这里写图片描述

getName2()运行结果:

这里写图片描述

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java解析XML数据通常使用Java API for XML Processing(JAXP),它是Java语言用于XML处理的标准API之一。JAXP提供了DOM解析器和SAX解析器。 DOM解析器会将整个XML文档加载到内存作为一个树形结构,可以通过遍历树来访问XML文档的各个元素和属性。以下是使用DOM解析解析XML数据的示例代码: ```java import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.w3c.dom.Node; import org.w3c.dom.Element; import java.io.File; public class XMLParser { public static void main(String argv[]) { try { File inputFile = new File("input.xml"); DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder dBuilder = dbFactory.newDocumentBuilder(); Document doc = dBuilder.parse(inputFile); doc.getDocumentElement().normalize(); System.out.println("Root element :" + doc.getDocumentElement().getNodeName()); NodeList nList = doc.getElementsByTagName("employee"); System.out.println("----------------------------"); for (int temp = 0; temp < nList.getLength(); temp++) { Node nNode = nList.item(temp); System.out.println("\nCurrent Element :" + nNode.getNodeName()); if (nNode.getNodeType() == Node.ELEMENT_NODE) { Element eElement = (Element) nNode; System.out.println("Employee id : " + eElement.getAttribute("id")); System.out.println("First Name : " + eElement.getElementsByTagName("firstName").item(0).getTextContent()); System.out.println("Last Name : " + eElement.getElementsByTagName("lastName").item(0).getTextContent()); System.out.println("Email : " + eElement.getElementsByTagName("email").item(0).getTextContent()); System.out.println("Salary : " + eElement.getElementsByTagName("salary").item(0).getTextContent()); } } } catch (Exception e) { e.printStackTrace(); } } } ``` 另外,SAX解析器是一种基于事件驱动的解析器,它逐行解析XML文档,可以在解析过程处理文档的各个元素和属性。使用SAX解析器需要实现org.xml.sax.ContentHandler接口的方法,以下是使用SAX解析解析XML数据的示例代码: ```java import javax.xml.parsers.SAXParser; import javax.xml.parsers.SAXParserFactory; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import java.io.File; public class XMLParser extends DefaultHandler { boolean bFirstName = false; boolean bLastName = false; boolean bEmail = false; boolean bSalary = false; public void startElement(String uri, String localName,String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("employee")) { String id = attributes.getValue("id"); System.out.println("Employee id : " + id); } else if (qName.equalsIgnoreCase("firstName")) { bFirstName = true; } else if (qName.equalsIgnoreCase("lastName")) { bLastName = true; } else if (qName.equalsIgnoreCase("email")) { bEmail = true; } else if (qName.equalsIgnoreCase("salary")) { bSalary = true; } } public void characters(char ch[], int start, int length) throws SAXException { if (bFirstName) { System.out.println("First Name: " + new String(ch, start, length)); bFirstName = false; } else if (bLastName) { System.out.println("Last Name: " + new String(ch, start, length)); bLastName = false; } else if (bEmail) { System.out.println("Email: " + new String(ch, start, length)); bEmail = false; } else if (bSalary) { System.out.println("Salary: " + new String(ch, start, length)); bSalary = false; } } public static void main(String argv[]) { try { File inputFile = new File("input.xml"); SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser saxParser = factory.newSAXParser(); XMLParser userhandler = new XMLParser(); saxParser.parse(inputFile, userhandler); } catch (Exception e) { e.printStackTrace(); } } } ``` 以上是两种常见的解析XML数据的方法,具体使用哪种方法取决于项目需求和个人喜好。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值