用DOM解析XML

二、XML解析
有两种解析方法:DOM(document object model)解析与SAX(simple API for XML)解析
XML解析开发包:
•JAXP:是SUN公司推出的解析标准实现。
•Dom4J:是开源组织推出的解析开发包。
•JDom:是开源组织推出的解析开发包。
JAXP(java API for XML processing)是javaSE的一部分,由三个子包组成
 
•org.w3c.dom:提供DOM方式解析XML的标准接口
•org.xml.sax:提供SAX方式解析XML的标准接口
•javax.xml:提供了解析XML文档的类
javax.xml.parsers包中,定义了几个工厂类。我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象。
•DocumentBuilderFactory
•SAXParserFactory

先看一下我们要解析的XML文档,文件名为books.xml
<?xml version="1.0" encoding="utf-8"?>
<书架>
    <>
        <书名>浪潮之巅</书名>    
        <作者>吴军</作者>
        <售价>39.00元</售价>
    </>
    <>
        <书名>数学之美</书名>
        <作者>吴军</作者>
        <售价>28.00元</售价>
    </>
 </书架>

 

import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

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;

public class ParseXml {
    public static void main(String[] args) {
            //多态,返回的是内部实现的一个子类的实例
        DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance();
        try {
            //多态
            DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
            //拿到文档对象模型,DOM树
            Document document=documentBuilder.parse("Books.xml");
            //从DOM树中取出标签名,返回一个结点list
            NodeList nodeList=document.getElementsByTagName("书");
            //取出下标为0的结点
            Node booksName0=nodeList.item(0);
            //取得结点的结点名称
            String name=booksName0.getNodeName();
            //取得该节点的父节点,返回一个结点node,调用getNodeName方法返回字符串
            String parentName=booksName0.getParentNode().getNodeName();
            System.out.println("结点名称:<"+name+">,父节点:<"+parentName+">");
            //===================================================================
            //二、打印某节点的所有元素节点 ,用第二个书结点
            Node bookname1=nodeList.item(1);
            NodeList childNodesList=bookname1.getChildNodes();
            int listLength=childNodesList.getLength();
            for (int i = 0; i < listLength; i++) {
                //因为XML中的空格换行等也属于子节点,故找到结点类型为1-->即元素,才打印
                if (childNodesList.item(i).getNodeType()==1) {
                String nodeName=childNodesList.item(i).getNodeName();
                System.out.println("第"+i+"个子节点<"+nodeName+">");
                }
            }
//            =========================================================================
//            三、修改某个元素结点的主体内容--->将"数学之美"改为"编程之美"
//            从子节点list中得到书名元素,用getTextContent
            String book2=childNodesList.item(1).getTextContent();
            System.out.println("更改之前的书名:"+book2);
            childNodesList.item(1).setTextContent("编程之美");
            System.out.println("更改之前的书名:"+childNodesList.item(1).getTextContent());
            //注意,更改了名字只是保存在内存中,并未保存到原文件中
        
//             =========================================================================
//             四、向指定元素节点中增加子元素节点,向第二本书增加一个子元素“评价”
            Element element= document.createElement("评价");
            element.setTextContent("五星");
            bookname1.appendChild(element);
//            ===============================================================================
//            五、删除元素结点,删除刚刚增加的元素
                Node comment=document.getElementsByTagName("评价").item(0);
                bookname1.removeChild(comment);
            
            //存盘的标准写法
            TransformerFactory tsf =TransformerFactory.newInstance();
             Transformer tsTransformer = tsf.newTransformer();
             tsTransformer.transform(
             new DOMSource(document), 
             new StreamResult("src/books.xml"));
            
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

 

javax.xml.parsers 包中的DocumentBuilderFactory用于创建DOM模式的解析器对象 , DocumentBuilderFactory是一个抽象工厂类,它不能直接实例化,但该类提供了一个newInstance方法 ,这个方法会自动创建一个工厂的对象并返回
调用 DocumentBuilderFactory.newInstance() 方法得到创建 DOM 解析器的工厂。
调用工厂对象的 newDocumentBuilder方法得到 DOM 解析器对象。
调用 DOM 解析器对象的 parse() 方法解析 XML 文档,得到代表整个文档的 Document 对象,进行可以利用DOM特性对整个XML文档进行操作了。
 

第二个例子
xml文档名为exam.xml
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<exam>
    <student idcard="111" examid="222">
        <name>张三</name>
        <location>沈阳</location>
        <grade>89</grade>
    </student>
    <student idcard="333" examid="444">
        <name>李四</name>
        <location>大连</location>
        <grade>97</grade>
    </student>
</exam>
import java.io.IOException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Attr;
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;

public class ExamXML {
    public static void main(String[] args) {
        //1. 向该xml文档里添加一个用户,姓名:王五,;location:铁岭;grade:99
        DocumentBuilderFactory documentBuilderFactory =    DocumentBuilderFactory.newInstance();
        try {
            DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder();
            //拿到dom树
             Document document=documentBuilder.parse("exam.xml");
             //拿到父节点
            Node superNode = document.getElementsByTagName("exam").item(0);
            Element studentElement=document.createElement("student");
            Element nameElement=document.createElement("name");
            Element locationElement=document.createElement("location");
            Element gradeElement=document.createElement("grade");
            nameElement.setTextContent("王五");
            locationElement.setTextContent("铁岭");
            gradeElement.setTextContent("99");
            studentElement.appendChild(nameElement);
            studentElement.appendChild(locationElement);
            studentElement.appendChild(gradeElement);
            superNode.appendChild(studentElement);
            NodeList WangwuInfo=document.getElementsByTagName("student").item(2).getChildNodes();
            for (int i = 0; i < WangwuInfo.getLength(); i++) {
                if (WangwuInfo.item(i).getNodeType()==1) {
                    System.out.println("第"+i+"个标签内的文本是:"+WangwuInfo.item(i).getTextContent());
                }    
            }
            //=========================================================================================
            //2. 给每个学生增加一条信息,性别
            
            NodeList studentList=document.getElementsByTagName("student");
            for (int i = 0; i < studentList.getLength(); i++) {
                Element gender=document.createElement("性别");
                studentList.item(i).appendChild(gender);
            }
            System.out.println("给每个学生增加性别标签,共有"+document.getElementsByTagName("性别").getLength()+"个学生增加");
            //==================================================================================
            //3. 删除第一个学生张三的所有信息。
            Node zhangsan=document.getElementsByTagName("student").item(0);
            superNode.removeChild(zhangsan);
            System.out.println("删除了张三后的学生标签有:"+studentList.getLength());
            //======================================================================================
            //4. 将第二个学生李四的姓名改为 李四光
                Node lisiInfo=document.getElementsByTagName("student").item(0);
                String lisiName=lisiInfo.getChildNodes().item(1).getTextContent();
                System.out.println("李四更改名字之前:"+lisiName);
                lisiInfo.getChildNodes().item(1).setTextContent("李四光");
                System.out.println("更改名字之后"+lisiInfo.getChildNodes().item(1).getTextContent());
            //=========================================================================================
            //5. 给每个学生增加一个ID属性
                //增加属性是元素对象的方法,故从Node强转为element类型
                for (int i = 0; i < studentList.getLength(); i++) {
                    Attr idAttr=document.createAttribute("id");
                    Element element=(Element) studentList.item(i);
                    element.setAttributeNode(idAttr);
                }    
                //强转
                Element element=(Element) studentList.item(0);
                //设置属性
                element.setAttribute("id", "1234");
                //打印属性
                System.out.println("id:"+element.getAttribute("id"));
                Element element1=(Element) studentList.item(1);
                element1.setAttribute("id", "98765");
                System.out.println("id:"+element1.getAttribute("id"));
            
            //存盘操作
                TransformerFactory tsf =TransformerFactory.newInstance();
                 Transformer tsTransformer = tsf.newTransformer();
                 tsTransformer.transform(
                 new DOMSource(document), 
                 new StreamResult("src/Exam.xml"));
            
            
        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (SAXException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TransformerConfigurationException e) {
            e.printStackTrace();
        } catch (TransformerException e) {
            e.printStackTrace();
        }
        
    }
}

 

 
posted @ 2016-01-19 08:57  sawder  阅读(172)  评论(0编辑  收藏  举报