zoukankan      html  css  js  c++  java
  • JavaXML解析的四种方法(连载)

    1. xml简介

      XML:指可扩展标记语言, Extensible Markup Language;类似HTML。XML的设计宗旨是传输数据,而非显示数据。

      一个xml文档实例:

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <company name="Tencent" address="深圳市南山区">
     3   <department deptNo="001" name="development">
     4     <employee id="devHead" position="minister">许刚</employee>
     5     <employee position="developer">工程师A</employee>
     6   </department>
     7   <department deptNo="002" name="education">
     8     <employee position="minister" telephone="1234567">申林</employee>
     9     <employee position="trainee">实习生A</employee>
    10   </department>
    11 </company>
    复制代码

      第一行是 XML 声明。它定义 XML 的版本 (1.0) 和所使用的编码.

      下一行描述文档的根元素:<company>开始,该根元素具有2个属性“name”,"address"。

      最后一行定义根元素的结尾。</company>。

        

      · XML 文档形成一种树结构

      · XML 文档必须包含根元素。该元素是所有其他元素的父元素。

      · XML 文档中的元素形成了一棵文档树。这棵树从根部开始,并扩展到树的最底端。

    所有元素均可拥有子元素: 

    复制代码
    1 <root>
    2 
    3   <child>
    4 
    5     <subchild>.....</subchild>
    6 
    7   </child>
    8 
    9 </root>
    复制代码

      父、子以及同胞等术语用于描述元素之间的关系。父元素拥有子元素。相同层级上的子元素成为同胞(兄弟或姐妹)。

    1.1 节点

      节点:XML文档中的所有节点组成了一个文档树(或节点树)。XML文档中的每个元素、属性、文本等都代表着树中的一个节点。树起始于文档节点,并由此继续伸出枝条,直到处于这棵树最低级别的所有文本节点为止,常用节点类型如下表所示:

    节点类型

    附加说明

    实例

    元素节点(Element)

    XML标记元素

    <company>…</company>

    属性节点(Attribute)

    XML标记元素的属性

    name=”Tencent”

    文本节点(Text)

    包括在XML标记中的文本段

    工程师A

    文档类型节点(DocumentType)

    文档类型声明

    ﹤!DOCTYPE…﹥

    注释节点Comment

    XmlComment类注释节点。

    <!—文档注释->

    (1) 节点关系

      通过上面的XML文档,我们构建出如下树状文档对象模型:

      

    复制代码
     1 <?xml version="1.0" encoding="UTF-8"?>    
     2 <bookstore>
     3 <book category="COOKING">
     4   <title lang="en">Everyday Italian</title> 
     5   <author>Giada De Laurentiis</author> 
     6   <year>2005</year> 
     7   <price>30.00</price> 
     8 </book>
     9 <book category="CHILDREN">
    10   <title lang="en">Harry Potter</title> 
    11   <author>J K. Rowling</author> 
    12   <year>2005</year> 
    13   <price>29.99</price> 
    14 </book>
    15 <book category="WEB">
    16   <title lang="en">Learning XML</title> 
    17   <author>Erik T. Ray</author> 
    18   <year>2003</year> 
    19   <price>39.95</price> 
    20 </book>
    21 </bookstore>
    复制代码

      再如上例xml文档:

      例子中的根元素是 <bookstore>。文档中的所有 <book> 元素都被包含在 <bookstore> 中。<book> 元素有 4 个子元素:<title>、< author>、<year>、<price>。

    (2)xml的特点

      a). XML 的属性值须加引号。

      · 与 HTML 类似,XML 也可拥有属性(名称/值的对)。

      · 在 XML 中,XML 的属性值须加引号。

      b). XML 文档必须有根元素.XML 文档必须有一个元素是所有其他元素的父元素。该元素称为根元素

      c). XML 标签对大小写敏感.

      · XML 元素使用 XML 标签进行定义。

      · XML 标签对大小写敏感。在 XML 中,标签 <Letter> 与标签 <letter> 是不同的。必须使用相同的大小写来编写打开标签和关闭标签。

      d). XML 中的注释语法: 

    <!-- This is a comment --> 

      e). XML 元素 vs. 属性

    复制代码
     1 <person sex="female">
     2   <firstname>Anna</firstname>
     3   <lastname>Smith</lastname>
     4 </person> 
     5 
     6 <person>
     7   <sex>female</sex>
     8   <firstname>Anna</firstname>
     9   <lastname>Smith</lastname>
    10 </person> 
    复制代码

      在第一行中,sex 是一个属性。在第7行中,sex 则是一个子元素。两个例子均可提供相同的信息。

    2. xml 解析

      xml解析方法有四种:  

      · DOM(JAXP Crimson 解析器):W3C为HTML和XML分析器制定的标准接口规范,基于树,可随机动态访问和更新文档的内容、结构、样式。

       · SAX(simple API for XML):不是W3C的标准,而是由XML-DEV邮件列表成员于1998年为Java语言开发的一种基于事件的简单API。基于事件,逐行解析,顺序访问XML文档,速度快,处理功能简单。

       · JDOM:鉴于DOM的低效率,而SAX又不能随机处理XML文档,Jason Hunter与Brett McLaughlin于2000年春天,开始创建一种能充分体现两者优势的API——JDOM(Java-based DOM,基于Java的DOM),它是一个基于Java的对象模型,树状结构,能使读取、操作和写入XML文档,比DOM更高效,比SAX更强大,但由于使用了大量的类而不使用接口导致灵活性降低。

      · DOM4J:DOM4J是一个易用的,开源的库,用于XML,XPath,XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX,JAXP。它提供了大量的接口,因此比JDOM更具有灵活性。

    2.1 DOM解析xml

      DOM(Document Object Model文档对象模型),是W3C为HTML和XML分析器制定的标准接口规范。   

    特点:独立于语言,跨平台(可以在各种编程和脚本语言中使用),需要将整个文档读入内存,在内存中创建文档树,可随即访问文档中的特定节点,对内存的要求比较高,经过测试,访问速度相对于其他解析方式较慢,适用于简单文档的随即处理。

    常用的节点属性:

    属性

    描述

    nodeName

    结点名称

    nodeValue

    结点内部值,通常只应用于文本结点

    nodeType

    节点类型对应的数字

    parentNode

    如果存在,指向当前结点的父亲结点

    childNodes

    子结点列表

    firstChild

    如果存在,指向当前元素的第一个子结点

    lastChild

    如果存在,指向当前元素的最后一个子结点

    previousSibling

    指向当前结点的前一个兄弟结点

    nextSibling

    指向当前结点的后一个兄弟结点

    attributes

    元素的属性列表

     常用的节点方法:

      

    操作类型

    方法原型

    描述

    访问节点

    getElementById(id)

    根据ID属性查找元素节点

    getElementsByName(name)

    根据name属性查找元素集

    getElementsByTagName(tagName)

    根据元素标记名称查找元素集

    创建节点

    createElement(tagName)

    创建元素节点

    createTestNode(string)

    创建文本节点

    createAttribute(name)

    创建属性节点

    插入和添加节点

    appendChild(newChild)

    添加子节点到目标节点上

    insertBefore(newChild,targetChild)

    将newChild节点插入到targetChild节点之前

    复制节点

    CloneNode(bool)

    复制该节点,由bool确定是否复制子节点

    删除和替换节点

    removeChild(childName)

    删除由childName指定的节点

    replaceChild(newChild,oldChild)

    用newChild替换oldChild

    属性节点操作

    getAttribute(name)

    返回目标对象指定属性名称为name的属性值

    setAttribute(name,value)

    修改目标节点指定属性名称为name的属性值为value

    removeAttribute(name)

    删除目标节点指定属性名称为name的属性

     (1)读取本地xml文档解析为对象的步骤: 

      * 首先利用DocumentBuilderFactory创建一个DocumentBuilderFactory实例;然后利用DocumentBuilderFactory创建DocumentBuilder

    //创建DocumentBuilderFactory工厂实例。
    DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance();
    //通过文档创建工厂创建文档创建器
    DocumentBuilder dBuilder = dbfactory.newDocumentBuilder();

      * 然后加载XML文档(Document)  : 通过文档创建器DocumentBuilder的parse方法解析参数URL指定的XML文档,并返回一个Document 对象。

    Document doc = dBuilder.parse(url);

      * 然后获取文档的根结点(Element),
      * 然后获取根结点中所有子节点的列表(NodeList),
      * 然后使用再获取子节点列表中的需要读取的结点。

     

     

     

    实例:第一种:Dom解析 (读取,增,删,改)

    在实际开发中多思考,灵活运用,非是难事儿!,对于程序员来讲,精彩的代码是如何想出来的,远比看到精彩的代码更加令人期望!

    books.xml

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <books>
        <book typeId="1">
            <bookId>001</bookId>
            <bookName>Maven实战</bookName>
            <bookPrice>51</bookPrice>
            <bookAuthor>陈晓斌</bookAuthor>
        </book>
        <book typeId="2">
            <bookId>002</bookId>
            <bookName>谈谈支付宝底层体系架构的大家</bookName>
            <bookPrice>151</bookPrice>
            <bookAuthor>程立</bookAuthor>
        </book>
        <book TypeId="3">
            <bookId>003</bookId>
            <bookName>预约死亡</bookName>
            <bookPrice>99</bookPrice>
            <bookAuthor>毕淑敏</bookAuthor>
        </book>
        <book TypeId="3">
            <bookId>003</bookId>
            <bookName>预约死亡</bookName>
            <bookPrice>56</bookPrice>
            <bookAuthor>毕淑敏</bookAuthor>
        </book>
    </books>
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import javax.xml.parsers.ParserConfigurationException;
    import javax.xml.transform.Result;
    import javax.xml.transform.Source;
    import javax.xml.transform.Transformer;
    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;
    
    public class Test {
        /**
         * XML读取 
         * @throws Exception
         */
        public static void xml()  throws Exception{
                    //1.构建一个工厂
                    DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance();
                    //2.构建builder1
                    DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
                    //3.Document对象
                    //一般放相对路径就可以了,程序自动在项目下寻址
                    Document document = dbBuilder.parse("books.xml");
                    //4.XML解析
                    NodeList list =document.getElementsByTagName("book");
                        for (int i = 0; i < list.getLength(); i++) {
                            Element item = (Element)list.item(i);
                            String attribute=item.getAttribute("typeId");
                            String bookId=item.getElementsByTagName("bookId").item(0).getTextContent();
                            String bookName=item.getElementsByTagName("bookName").item(0).getTextContent();
                            String bookPrice=item.getElementsByTagName("bookPrice").item(0).getTextContent();
                            String bookAuthor=item.getElementsByTagName("bookAuthor").item(0).getTextContent();
                            System.out.println(bookId);
                            System.out.println(bookName);
                            System.out.println(bookPrice);
                            System.out.println(bookAuthor);
                            //System.out.println(attribute);
                            System.out.println("-----------------");
                        }
        }
        /**
         * XML添加
         * @throws Exception
         */
        public static void insert() throws Exception{
                    //1.构建一个工厂
                    DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance();
                    //2.构建builder1
                    DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
                    //3.Document对象
                    Document document = dbBuilder.parse("books.xml");
                    //1.伪造内存中的节点,游离节点
                    Element book = document.createElement("book");
                    book.setAttribute("TypeId", "3");
                    Element bookId=document.createElement("bookId");
                    bookId.setTextContent("003");
                    Element bookName = document.createElement("bookName");
                    bookName.setTextContent("预约死亡");
                    Element bookPrice = document.createElement("bookPrice");
                    bookPrice.setTextContent("56");
                    Element bookAuthor = document.createElement("bookAuthor");
                    bookAuthor.setTextContent("毕淑敏");
                    book.appendChild(bookId);
                    book.appendChild(bookName);
                    book.appendChild(bookPrice);
                    book.appendChild(bookAuthor);
                    
                    //1.将Book节点和整篇文档建立关联
                    document.getElementsByTagName("books").item(0).appendChild(book);
                    //1.传输工厂
                    TransformerFactory transformerFactory = TransformerFactory.newInstance();
                    //2.传输器
                    Transformer transformer = transformerFactory.newTransformer();
                    Source source = new DOMSource(document);
                    StreamResult result = new StreamResult("books.xml");
                    //3.传输方法
                    transformer.transform(source, result);
                    System.out.println("save ok!");
        }
        /**
         * XML修改
         * @throws Exception
         */
        public static void  update() throws Exception{
            //1.构建一个工厂
            DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance();
            //2.构建builder1
            DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
            //3.Document对象
            Document document = dbBuilder.parse("books.xml");
            //修改指定item的书的价格
                    //"E:/eclispsespace/JavaOOP-Day-09-0100/books.xml"
                    Element book = (Element)document.getElementsByTagName("book").item(2);
                    book.getElementsByTagName("bookPrice").item(0).setTextContent("99");
                    //传输工程
                    TransformerFactory transformerFactory = TransformerFactory.newInstance();
                    //传输器
                    Transformer transformer =transformerFactory.newTransformer();
                    Source source = new DOMSource(document);
                    Result result = new StreamResult("books.xml");
                    transformer.transform(source, result);
                    System.out.println("修改完毕!");
        }
        /**
         * XML删除
         * @throws Exception
         */
        public static void  delXml() throws Exception{
            //1.构建一个工厂
            DocumentBuilderFactory dbFactory =DocumentBuilderFactory.newInstance();
            //2.构建builder1
            DocumentBuilder dbBuilder = dbFactory.newDocumentBuilder();
            //3.Document对象
            //一般放相对路径就可以了,程序自动在项目下寻址
            Document document = dbBuilder.parse("books.xml");
            Element book = (Element)document.getElementsByTagName("book").item(2);
            document.getElementsByTagName("books").item(0).removeChild(book);
            //传输工程
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            //传输器
            Transformer transformer = transformerFactory.newTransformer();
            Source source = new DOMSource(document);
            Result result =new StreamResult("books.xml");
            transformer.transform(source, result);
            System.out.println("删除成功!");
            
        }
        public static void main(String[] args) throws Exception {
                //xml();//读取
                //insert();//增加
                //update();//修改
            delXml() ;//删除
            
        }
    
    }

     第二种:使用Dom4j解析XML

    Dom4j:

       Dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API,具有性能优异、功能强大和极其易使用的特点,它的性能超过sun公司官方的dom技术,同时它也是一个开放源代码的软件,可以在SourceForge上找到它。在IBM developerWorks上面还可以找到一篇文章,对主流的Java XML API进行的性能、功能和易用性的评测,所以可以知道dom4j无论在哪个方面都是非常出色的。如今可以看到越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。这已经是必须使用的jar包,Hibernate也用它来读写文件。

    所需jar包:dom4j-1.6.1.jar

    实例图:

     XML文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <people city="beijing">
        <student name="milton" age="22"></student>  
        <student name="lego" age="23"></student>  
        <teacher name="bruce" age="27"></teacher>  
        <teacher name="ziven" age="29"></teacher>
    </people>

    对应entity:

    People类:

    Student类:

    Teacher类:

     TestXml类:

    package cn.resolve.dom4j;
    import java.io.File;
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import org.dom4j.Document;
    import org.dom4j.DocumentException;
    import org.dom4j.Element;
    import org.dom4j.io.SAXReader;
    import cn.resolve.entity.People;
    import cn.resolve.entity.Student;
    import cn.resolve.entity.Teacher;
    /**
     * 测试使用dom4j解析XML
     * @author Zhang
     *
     */
    public class TestXml {
        public static People xmlParse(String xmlPath){
            File xmlFile = new File(xmlPath);
            System.out.println(xmlFile.getPath());
            //判断文件是否存在
            if (xmlFile.exists()) {
                SAXReader reader = new SAXReader();
                People people = new People();
                try {
                    //读入文档流
                    Document document = reader.read(xmlFile);
                    //获取根节点
                    Element root =document.getRootElement();
                    //创建两个对象集合
                    List<Student> students = new ArrayList<Student>();
                    List<Teacher> teachers = new ArrayList<Teacher>();
                    //拿到attribute属性的值
                    people.setCity(root.attributeValue("city"));
                    //解析student节点
                    for (Iterator iterator = root.elementIterator("student");iterator.hasNext();) {
                    Element eStudent= (Element)iterator.next();
                    Student student = new Student(eStudent.attributeValue("name"),Integer.parseInt(eStudent.attributeValue("age")));
                    //添加到集合
                    students.add(student);
                    }
                    //解析teacher节点
                    for (Iterator iterator= root.elementIterator("teacher");iterator.hasNext();) {
                        Element eTeacher = (Element)iterator.next();
                        Teacher teacher = new Teacher(eTeacher.attributeValue("name"),Integer.parseInt(eTeacher.attributeValue("age")));
                        teachers.add(teacher);
                    }
                    people.setStudent(students);
                    people.setTeacher(teachers);
                    System.out.println("success!");
                } catch (DocumentException e) {
                    e.printStackTrace();
                }
                return people;
            }else {
                System.out.println("file is not exist!");
                return null;
            }
        }
        public static void main(String[] args) {
                String xmlpath = "src/people.xml";
                //解析people.xml
                People people =xmlParse(xmlpath);
                System.out.println("file full path is xmlpath ");    
                List<Teacher> teachers = new  ArrayList<Teacher>();
                List<Student> students = new  ArrayList<Student>();
                System.out.println(people.getCity());
                //处理解析结果
                for (Student s : students) {
                    System.out.println("学生姓名/t/t年龄");
                    System.out.println(s.getName()+":"+s.getAge());
                }
                for (Teacher t: teachers) {
                    System.out.println("教师姓名/t/t年龄");
                    System.out.println();
                }
        }
    }
  • 相关阅读:
    iOS数据持久化—FMDB框架的简单介绍
    iOS数据持久化—SQLite常用的函数
    多段图动态规划dp
    Cucumber测试驱动开发
    敏捷开发XP
    Android 小票打印USB
    TextInputLayout 用法
    Snackbar 提醒
    PermissionDispatcher 运行时权限框架
    Tinker 热修复
  • 原文地址:https://www.cnblogs.com/java-123/p/9110942.html
Copyright © 2011-2022 走看看