解析XML数据

Posted 猪八戒1.0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了解析XML数据相关的知识,希望对你有一定的参考价值。

下面只解析,如果想用解析后的数据创建对象,直接写在其中即可

若vehicles.xml

<vehicles>
    <cars>
        <car id="1">
            <name>战神</name>
            <oil>20</oil>
            <loss>0</loss>
            <brand>长城</brand>
        </car>
        <car id="2">
            <name>跑得快</name>
            <oil>40</oil>
            <loss>20</loss>
            <brand>红旗</brand>
        </car>
    </cars>
    <trucks>
        <truck id="3">
            <name>大力士</name>
            <oil>20</oil>
            <loss>0</loss>
            <load>5吨</load>
        </truck>
        <truck id="4">
            <name>大力士二代</name>
            <oil>30</oil>
            <loss>30</loss>
            <load>10吨</load>
        </truck>
    </trucks>
</vehicles>

1.采用Java默认的Dom解析xml

package test;

import java.io.IOException;

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

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 * 采用 DOM 方式解析 XML 数据
 */
public class TestDOM 
    /**
     * 文件解析
     * @param filename 文件名
     */
    public void parseFile(String filename)
        try 
            //创建解析器工厂
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            //通过解析器工厂获得DOM解析器
            DocumentBuilder db = dbf.newDocumentBuilder();

            //解析指定XML文档,得到DOM节点树
            Document doc = db.parse(filename);
            //得到根节点
            NodeList vehicles = doc.getChildNodes();
            System.out.println(" `租车系统` 中共有" + vehicles.getLength() + "种类型的车!");

            //得到所有<truck>节点列表信息
            NodeList truckList = doc.getElementsByTagName("truck");
            System.out.println(" `租车系统` 中共有" + truckList.getLength() + "辆卡车!");

            //遍历所有卡车
            for (int i = 0; i < truckList.getLength(); i++) 
                //获取索引为i的卡车
                Node truck = truckList.item(i);
                //获取卡车属性值并显示
                Element element = (Element) truck;
                String idValue = element.getAttribute("id");
                //以下通过属性名获得属性节点,再通过getNodeValue()获得属性值
                //Node attr = element.getAttributeNode("id");
                //String idValue = attr.getNodeValue();
                System.out.println("id为" + idValue + "的卡车信息为:");
                //获取索引为i的卡车详细信息并输出
                for (Node node = truck.getFirstChild(); node != null; node = node.getNextSibling()) 
                    //根据节点类型进行判断,显示元素节点信息,如 <oil>20</oil>
                    if (node.getNodeType() == Node.ELEMENT_NODE)
                        //元素节点的节点名为标签名,如oil
                        String name = node.getNodeName();
                        //元素节点<oil>20</oil>下第一个子节点为文本节点20,得到节点值20
                        String value = node.getFirstChild().getNodeValue();
                        System.out.println("  " + name + ":" + value + ";");
                    
                
            
         catch (ParserConfigurationException e) 
            e.printStackTrace();
         catch (SAXException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
    

    public static void main(String[] args) 
        new TestDOM().parseFile("src//test//vehicles.xml");
    

2.使用 Dom4j 解析 XML 数据

package test;


import java.util.List;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
 * Dom4j 解析 XML 文档数据
 * @author 小桃子
 */
public class TestDom4j 
    /**
     * 解析文件
     * @param filename 路径+文件名
     */
    public void parseFile(String filename) 
        // 创建 SAX 解析对象
        SAXReader reader = new SAXReader();

        try 
            // 获取文档对象
            Document document = reader.read(filename);

            // 获取根元素
            Element root = document.getRootElement();

            // 获取子元素
            Element cars = root.element("cars");
            Element trucks = root.element("trucks");

            // 调用数据获取的方法
            this.getData(cars, "car");
            //this.getData(trucks, "truck");
         catch (DocumentException e) 
            e.printStackTrace();
        
    
    /**
     * 获取子元素以及子元素文本数据
     * @param element 子元素对象
     * @param elementName 子元素标记名
     */
    public void getData(Element element, String elementName)
        // 获取子元素的列表集合
        List<Element> elementList = element.elements(elementName);
        for (Element e : elementList) 
            //获取属性信息
            Attribute attid = e.attribute("id");
            if(attid != null)
                System.out.println("编号:" + attid.getValue());
            
            String attsupplier = e.attributeValue("supplier");
            if(attsupplier != null)
                System.out.println("供应商编号:" + attsupplier);
            
            //获取子元素文本数据
            Element name = e.element("name");
            System.out.println("名称:" + name.getText());
            System.out.println("油量:" + e.elementText("oil"));
            System.out.println("损耗:" + e.elementText("loss"));
//            if("car".equals(elementName))
//                Element brand = e.element("brand");
//                System.out.println("品牌:" + brand.getText());
//            else
//                System.out.println("载重:" + e.elementText("load"));
//            
            System.out.println("----------");
        
    

    public static void main(String[] args) 
        new TestDom4j().parseFile("src//test//vehicles.xml");
    

如果book2.xml

<?xml version="1.0" encoding="UTF-8"?>
<books>
    <book id="100003">
        <bookname>深入理解Java虚拟机:JVM高级特性与最佳实践</bookname>
        <bookauthor>周志明</bookauthor>
        <bookprice>79</bookprice>
    </book>
    <book id="100004">
        <bookname> Java多线程编程核心技术</bookname>
        <bookauthor>高洪岩</bookauthor>
        <bookprice>99</bookprice>
    </book>
    <book id="100005">
        <bookname>Java高并发编程详解:并发核心库+多线程设计</bookname>
        <bookauthor>汪文君</bookauthor>
        <bookprice>188</bookprice>
    </book>
</books>
package test;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.util.List;

public class Dom4jParseXml 
    public void parseFile(String filename) 
        // 创建 SAX 解析对象
        SAXReader reader = new SAXReader();

        try 
            // 获取文档对象
            Document document = reader.read(filename);

            // 获取根元素
            Element root = document.getRootElement();



            // 调用数据获取的方法
            this.getData(root, "book");

         catch (DocumentException e) 
            e.printStackTrace();
        
    
    /**
     * 获取子元素以及子元素文本数据
     * @param element 子元素对象
     * @param elementName 子元素标记名
     */
    public void getData(Element element, String elementName)
        // 获取子元素的列表集合
        List<Element> elementList = element.elements(elementName);
        for (Element e : elementList) 
            //获取属性信息
            Attribute attid = e.attribute("id");
            if(attid != null)
                System.out.println("编号:" + attid.getValue());
            

            //获取子元素文本数据
            Element bookname = e.element("bookname");
            System.out.println("书名:" + bookname.getText());
            System.out.println("作者:" + e.elementText("bookauthor"));
            System.out.println("价格:" + e.elementText("bookprice"));

        
    
    public static void main(String[] args) 
        new Dom4jParseXml().parseFile("src//test//books2.xml");
    

 运行结果:

3.采用 SAX 方式解析 XML 数据

        SAX(Simple API for XML)是一种速度更快、更有效的解析 XML 文档的方法。它不需要一次性建立一个完整的 DOM 树,而是读取文档时激活事件进行处理。

        DOM 是 W3C 标准,提供的是标准的解析方式,但其解析效率一直不尽如人意。这是因为 DOM 解析 XML 文档时,把所有内容一次性装载入内存,并构建一个驻留在内存中的节点树。如果需要解析的 XML 文档过大,或者只对该文档中的一部分内容感兴趣,这种做法就会引起性能问题。

        SAX 既是一个接口,也是一个软件包。

        SAX 在解析 XML 时是事件驱动型的,它的工作原理简单地说就是对文档进行顺序扫描,当扫描到文档开始与结束、元素开始与结束等地方时通知事件处理程序,由事件处理程序做相应动作,然后继续同样的扫描,直至文档结束。

        SAX 的缺点也很明显,要用 SAX 对 XML 文档进行解析时,就要实现多个事件处理程序,用来处理可能触发的事件,对程序员而言操作起来相对复杂。

package test;

import java.io.File;
import java.io.IOException;

import javax.xml.parsers.ParserConfigurationException;
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;

/**
 * 采用 SAX 方式解析 XML 数据
 */
public class TestSAX extends DefaultHandler 
    private String tagName;

    // 开始解析xml文件 (只执行一次)
    @Override
    public void startDocument() throws SAXException 
        System.out.println("SAX解析开始...");
    

    // 解析xml文件 结束(只执行一次)
    @Override
    public void endDocument() throws SAXException 
        System.out.println("SAX解析结束...");
    

    // 开始解析xml元素(执行多次)
    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException 
        if (qName.equals("car")) 
            int id = Integer.parseInt(attributes.getValue(0));
            System.out.println(id);
        
        if (qName.equals("truck")) 
            int id = Integer.parseInt(attributes.getValue(0));
            System.out.println(id);
        
        this.tagName = qName;
    

    // 结束 解析xml元素(执行多次)
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException 
        if (qName.equals("car")) 
            System.out.println("一个car标签解析完毕");
        
        if (qName.equals("truck")) 
            System.out.println("一个truck标签解析完毕");
        
        this.tagName = null;
    

    // 在startElement、endElement 之间调用多次
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException 
        if (this.tagName != null) 
            String data = new String(ch, start, length);// ch[] -> String
            if (this.tagName.equals("name")) 
                System.out.print(data + "\\t");
            
            if (this.tagName.equals("oil")) 
                System.out.print(Integer.parseInt(data) + "\\t");
            

            if (this.tagName.equals("loss")) 
                System.out.print(Integer.parseInt(data) + "\\t");
            

            if (this.tagName.equals("brand")) 
                System.out.println(data);
            

            if (this.tagName.equals("load")) 
                System.out.println(data);
            
        
    

    /**
     * SAX 解析
     * @param filename 解析文件
     */
    public void paresFile(String filename) 
        try 
            SAXParser parser = SAXParserFactory.newInstance().newSAXParser();
            parser.parse(new File(filename), this);
         catch (ParserConfigurationException e) 
            e.printStackTrace();
         catch (SAXException e) 
            e.printStackTrace();
         catch (IOException e) 
            e.printStackTrace();
        
    

    public static void main(String[] args) throws Exception 
        new TestSAX().paresFile("src//test//vehicles.xml");
    

运行结果:

<?xml version="1.0" encoding="UTF-8"?>
<boo>
<books>
    <book id="100003">
        <bookname>深入理解Java虚拟机:JVM高级特性与最佳实践</bookname>
        <bookauthor>周志明</bookauthor>
        <bookprice>79</bookprice>
    </book>
    <book id="100004">
        <bookname> Java多线程编程核心技术</bookname>
        <bookauthor>高洪岩</bookauthor>
        <bookprice>99</bookprice>
    </book>
    <book id="100005">
        <bookname>Java高并发编程详解:并发核心库+多线程设计</bookname>
        <bookauthor>汪文君</bookauthor>
        <bookprice>188</bookprice>
    </book>
</books>
</boo>
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;


import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.io.File;
import java.io.IOException;

public class SaxParseXml extends DefaultHandler 
    /**
     * 解析XML文件开始时调用
     * @throws SAXException
     */
    public void parseFile(String filename) throws ParserConfigurationException, SAXException, IOException

        //(1)创建SAXParserFactory对象
        SAXParserFactory saxParserFactory = SAXParserFactory.newInstance();
        //(2)通过SAXParserFactory对象创建SAXParser对象
        SAXParser parser = saxParserFactory.newSAXParser();
        //(3)创建DefaultHandler的子类
        SaxParseXml bookDefaultHandler = new SaxParseXml();
        //(4)调用parse()方法
        parser.parse(filename,bookDefaultHandler);


    
    @Override
    public void startDocument() throws SAXException 
        super.startDocument();
        System.out.println("books2文档开始解析");
    

    /**
     * 解析XML文件结束时调用
     * @throws SAXException
     */
    @Override
    public void endDocument() throws SAXException 
        super.endDocument();
        System.out.println("books2文档结束解析");
    


     //解析XML文件中的节点时调用

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException 
        super.startElement(uri, localName, qName, attributes);
        if("book".equals(qName))
            //获取所有属性的长度
            int length = attributes.getLength();
            //遍历属性
            for(int i = 0; i < length; i++)
                String name = attributes.getQName(i);
                String value = attributes.getValue(i);
                //System.out.println("属性名:"+name+"\\t属性值:"+value);
                System.out.println("编号:"+value);
            
        else if(!"books".equals(qName) && !"book".equals(qName))
            //System.out.print("节点名:"+qName+"\\t");
            if(qName=="bookname")
                System.out.print("书名:");
            
            else if(qName=="bookauthor")
                System.out.print("作者:");
            
            else if(qName=="bookprice")
                System.out.print("价格:");
            
        
    


    //解析XML文件中的节点结束时调用
    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException 
        super.endElement(uri, localName, qName);
    


    //获取节点值
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException 
        super.characters(ch, start, length);
        String value = new String(ch, start, length);
        if (!"".equals(value.trim())) 
            //System.out.println("节点值:" + value);
            System.out.println(value);
        
    

    public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException 
       
        new SaxParseXml().parseFile("/home/project/books2.xml");

    

以上是关于解析XML数据的主要内容,如果未能解决你的问题,请参考以下文章

致命错误:未捕获的错误:在解析数据时调用字符串上的成员函数 find()

CDS Sketch Practise ! 今天教你画卡车!

使用时间和服务日数据计算卡车的服务日期

CharacterEncodingFilter详解及源码解析

创建在特定事件发生时调用的自定义 appsync 解析器或 lambda 函数

struts组件概述