码迷,mamicode.com
首页 > 编程语言 > 详细

javaEE学习笔记【03】XML操作

时间:2015-10-13 17:07:22      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

  1. XML简介
    XML即可扩展的标记语言。因此该语言中所有的标签都是没有预先定义的,开发者可以自己随意的指定。
    目前为止所有的标记的语言都属于开源的语言。由W3C组织进行一个基本的维护。
    因此大家学习这些语言的时候应该参考W3C公布的文档。
  2. XML作用
    1.可以用作软件的配置文件。
    2.可以实现独立平台的数据传输。 C、 XML 、Java  、天气预报
    3.Web Service。
    4.可以描述带关系的数据。
  3. XML声明指令
    语法:
    1
    <?xml version=””  encoding=””  standalone=”” ?>
    xml 是一个xml文件的指令名通知解析器以XML的方式进行解析
    (1)version 指定XML的版本,目前只能是1.0
    (2)encoding 指定XML文件的被解析时候的解码方式,一般的值是GBK或UTF-8
    (3)standalone 指定该文件时否是独立文件。默认值是yes,也可是no
  4. 细节体验:
    (1)<>和?号之间不能有任何字符包含空格
    (2)?和xml指令名之间不能有任何的字符包含空格
    (3)版本号只能是1.0
    (4)编码和解码要一致
    (5)三个属性出现的顺序是固定的;【version / encoding / standalone】
  5. 一个XML文件中只能有一个根元素包含其他元素
  6. 但是如果在标签体中大量的出现特殊字符,那么如果要使用转移字符那么就太繁琐了。
    解决方案:CDATA区域按照原格式输出
    1
    2
    3
    4
    5
    6
    <![CDATA[
       <html>
          <head></head>
          <body></body>
       </html>
    ]]>
  7. XML的样式表跟css差不多一致
  8. XML官方采用DTD约束,较为简单的操作但是功能性不是非常强大
  9. Schema约束XML
    Schema约束技术定义了丰富的元素类型可以很细致的对XML元素和属性以及出现的次数等进行约束,但是正是由于过于详细那么导致该技术比较复杂。因此开发者只需要学会Schema文件的引入以及读懂别人的Schema基本的语法可以修改即可。
  10. 使用了一个绝对路径进行资源的访问,无法获取该资源?
    在项目中一定不要使用绝对路径进行资源的操作。
  11. 在项目中引入了两个jar包,但是在编码的时候没有提示?
    导入的一定要是jar包,业务逻辑一定要写在方法
  12. 熟练掌握XML的基本语法结构即可。
    了解DTD和Schema的语法规则
    掌握约束文件的引入方法(Spring框架)
    大家只需要可以直接看懂别人写的DTD约束进行基本的修改即可
  13. JAXP技术
    JAXP即Java Api for Xml Processing该API主要是SUN提供的用于解析XML数据的一整套解决方案,主要包含了DOM和SAX解析技术。大家可以参见SUN的以下两个包:
    javax.xml.parsers.* 【主要存储的是解析器】
    org.w3c.dom.*或org.w3c.sax.* 【主要存储的是DOM解析或SAX解析需要的API】
    DOM解析主要采用DOM树的方式进行XML的数据解析。如:JavaScript中的DOM操作
    SAX解析主要采用事件的方式进行XML的数据解析。如:JavaScript中的事件机制
  14. DOM解析1.    准备要解析user.xml文件
    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8"?>
    <!-- 1. 编写要解析的XML文件 -->
    <users>
    </users>
    2.    获取解析器, 提供获取解析器的方法
    1
    2
    3
    4
    5
    6
    7
    public static DocumentBuilder getParser()throws Exception{
        // 创建工厂类对象
        DocumentBuilderFactory factory =DocumentBuilderFactory.newInstance();
        // 获取解析器对象
        DocumentBuilder parser = factory.newDocumentBuilder();
        return parser;
    }
    3. 获取解析的DOM树对象,提供获取DOM数据的方法
    1
    2
    3
    4
    5
    6
    7
    public static Document getDOM(File file)throws Exception{
        // 获取解析器
        DocumentBuilder parser = getParser();
        // 解析数据
        Document dom = parser.parse(file);
        return dom;
    }
    4. 获取根元素,提供解析根元素的数据的方法
    1
    2
    3
    4
    5
    6
    7
    8
    public static void getRoot(File file)throws Exception{
        // 获取DOM树
        Document dom = getDOM(file);
        // 遍历dom树找根元素
        Node node = dom.getElementsByTagName("users").item(0);
        // 输出根元素的名
        System.out.println(node.getNodeName());
    }
    5. 通过关系获取根元素, 提供解析根元素的数据的方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public static void getRoot(File file)throws Exception{
         // 获取DOM树
         Document dom = getDOM(file);
         // 遍历dom树找根元素
         Node node = dom.getElementsByTagName("users").item(0);
         // 输出根元素的名
         System.out.println(node.getNodeName());
         // 根据节点直接的关系获取根元素
         NodeList list = dom.getChildNodes();
         Node root = list.item(0);
         System.out.println(root.getNodeName());
         root = dom.getFirstChild();
         System.out.println(root.getNodeName());
         root = dom.getLastChild();
         System.out.println(root.getNodeName());
     }
    6. 添加元素, 添加一个user节点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static Document addElement(File file)throws Exception{
        // 获取DOM树
        Document dom = getDOM(file);
        // 创建user元素
        Element user = dom.createElement("user");
        Element name = dom.createElement("name");
        Element age = dom.createElement("age");
        Element address = dom.createElement("address");
     
        name.setTextContent("焦宁波");
        age.setTextContent("28");
        address.setTextContent("天河区");
        // 建立关系
        Element root = (Element) dom.getFirstChild();
        user.appendChild(name);
        user.appendChild(age);
        user.appendChild(address);
        root.appendChild(user);
        // 返回修改后的DOM树对象
        return dom;
    }
    7. 为了让内存中的修改的DOM树持久化到磁盘文件需要定义以下方法
    提供一个工具方法将内存中的DOM树存储到磁盘的指定文件中
     
    1
    2
    3
    4
    5
    6
    7
    8
    public static void writeDOM2XML(Document dom,File file)throws Exception{
         // 获取转换器的工厂类对象
         TransformerFactory factory = TransformerFactory.newInstance();
         // 获取转换器对象
         Transformer trans = factory.newTransformer();
         // 转换
         trans.transform(new DOMSource(dom), new StreamResult(new FileOutputStream(file)));
     }
    思考:以上的代码为什么可以直接的处理中文?
    文件本身是UTF-8编码存储的和使用的是字节流。
    8. 修改元素,修改第二个user的年龄为30岁
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static Document modifyElement(File file)throws Exception{
        // 获取DOM树
        Document dom = getDOM(file);
        // 获取第二个age元素
        Node age2 = dom.getElementsByTagName("age").item(1);
        // 设置文本值
        age2.setTextContent("30");
        return dom;
    }
    9. 删除元素, 删除第一个user节点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static Document removeElement(File file)throws Exception{
        // 获取DOM树
        Document dom = getDOM(file);
        // 获取user的父亲
        Node users = dom.getFirstChild();
        // 获取需要断绝关系的孩子节点
        Node user1 = dom.getElementsByTagName("user").item(0);
        // 断绝关系
        users.removeChild(user1);
        return dom;
    }
    以上的代码存在代码的重复。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static Document removeElement(File file)throws Exception{
            // 获取DOM树
            Document dom = getDOM(file);
            // 获取user的父亲
            Node users = dom.getFirstChild();
            Node user1 = users.getChildNodes().item(1);
            users.removeChild(user1);
            return dom;
        }
    10. 加强使用关系获取元素,使用关系获取节点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public static void searchElement(File file)throws Exception{
        // 8.1获取DOM树
        Document dom = getDOM(file);
        // 8.2获取第二个user的所有的子元素并输入元素名
        Element user2 = (Element) dom.getElementsByTagName("user").item(1);
        // 8.3获取所有的儿子
        NodeList list = user2.getChildNodes();
        // 8.4遍历所有的孩子
        for(int i = 0;i<list.getLength();i++){
            Node node = list.item(i);
            System.out.println(node.getNodeName());
        }
        // 8.5获取第二个user的address元素
        Element address2 = (Element) list.item(2);
        System.out.println(address2.getNodeName());
        Node age2 = address2.getPreviousSibling();
        System.out.println(age2.getNodeName());
     
        Element name2 = (Element) list.item(0);
        System.out.println(name2.getNodeName());
        age2 = name2.getNextSibling();
        System.out.println(age2.getNodeName());
     
    }
    11. 属性的操作,属性操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    public static Document optionAttribute(File file)throws Exception{
            // 获取DOM树
            Document dom = getDOM(file);
            // 获取所有的user元素
            NodeList list = dom.getElementsByTagName("user");
            // 遍历节点
            for (int i = 0; i < list.getLength(); i++) {
                Element user = (Element)list.item(i);
                // 添加属性
                user.setAttribute("id", "00"+(i+1));
            }
            // 获取属性
            Element user2 = (Element) list.item(1);
            String value = user2.getAttribute("id");
            System.out.println(value);
            // 修改属性
            user2.setAttribute("id", "007");
            // 删除属性
            user2.removeAttribute("id");
            return dom;
        }
    总结:在实际的项目开发中我们经常遇到的XML数据时比较大的,如果使用DOM进行数据的解析,那么首先在内存中会形成一个DOM树结构。因此容易导致内存的一个溢出。所以不建议大家使用DOM解析进行操作较大的XML数据。如果只是需要进行XML文件的数据获取,那么推荐使用SAX解析。
    SAX解析
    SAX即Simple Api for Xml就是一个简单的操作XML数据的一套SUN提供的API机制。
    SAX采用的解析的原理是基于事件触发的机制。
    SAX技术只能进行XML数据的读取。
    (1)准备需要解析的XML文件linkmans.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <linkmans>
        <linkman>
            <name>jack</name>
            <phone>18663243245</phone>
            <email>jack@163.com</email>
        </linkman>
        <linkman>
            <name>张三</name>
            <phone>1353243247</phone>
            <email>zs@126.com</email>
        </linkman>
    </linkmans>
    2.    获取SAX解析器
    1
    2
    3
    4
    5
    6
    public static SAXParser getParser()throws Exception{
        // 获取解析器工厂类对象
        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser parser = factory.newSAXParser();
        return parser;
    }
    3.    解析数据
    1
    2
    3
    4
    5
    6
    public static void getElement(File file,DefaultHandler dh) throws Exception{
        // 获取解析器
        SAXParser parser = getParser();
        // 调用解析方法
        parser.parse(file, dh);
    }
    4. 创建一个继承自DefaultHandler类的MyHandler.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class MyHandler extends DefaultHandler {
        // 当文档开始解析的时候自动执行
        public void startDocument() throws SAXException {
            super.startDocument();
            System.out.println("XML文档开始解析...");
        }
        // 遇到一个开始元素自动执行
        public void startElement(String uri, String localName, String name,
                Attributes attributes) throws SAXException {
            super.startElement(uri, localName, name, attributes);
            System.out.println("元素"+name+"开始...");
        }
        // 遇到文本内容自动执行
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            super.characters(ch, start, length);
            System.out.println("文本内容"+new String(ch,start,length));
        }
        // 遇到元素结束自动执行
        public void endElement(String uri, String localName, String name)
                throws SAXException {
            super.endElement(uri, localName, name);
            System.out.println("元素"+name+"结束...");
        }
        // 文档解析完毕的时候自定执行
        public void endDocument() throws SAXException {
            super.endDocument();
            System.out.println("XML文档解析结束...");
        }
    }
    5. 在main函数中调用解析元素的方法
    1
    2
    3
    4
    5
    public static void main(String[] args)throws Exception {
           File file = new File("linkmans.xml");
           MyHandler handler = new MyHandler();
           getElement(file,handler);
       }
    通过以上的程序发现其实SAX解析的时候只是需要开发者传递相应的事件处理器对象即可(继承自DefaultHandler的类)。
    举例1:创建一个事件处理器获取XML中的指定的节点数据。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class OptionDataHandler extends DefaultHandler {
        // 定义一个成员变量记录标签的名
        private String name = null;
        // 定义一个统计次数的变量
        private int count = 0;
        // 遇到一个开始元素自动执行
        public void startElement(String uri, String localName, String name,
                Attributes attributes) throws SAXException {
            super.startElement(uri, localName, name, attributes);
            this.name = name;
            if("name".equals(this.name)){
                this.count++;
            }
        }
        // 遇到文本内容自动执行
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            super.characters(ch, start, length);
            // 判断是否是name元素
            if("name".equals(this.name) && this.count == 2){
               System.out.println(new String(ch,start,length));  
            }
        }
    }
     使用SAX解析XML数据并进行数据的集合封装
    其实使用任何的XML解析技术来解析XML数据都需要后期的数据封装,如果只是单独的获取某一个节点的值是没有任何含义的。因此需要将XML的数据解析好之后以对象的方式进行封装到指定的集合中便于其他应用程序的处理。
    代码实现步骤
    1. 实现一个Linkman.java的javabean对象
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    public class Linkman {
        private String name;
        private String phone;
        private String email;
        public Linkman() {
            super();
        }
        public Linkman(String name, String phone, String email) {
            super();
            this.name = name;
            this.phone = phone;
            this.email = email;
        }
        // 省略get和set方法
    }
    3.    创建一个用于封装的事件处理器Listhandler.java
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    public class ListHandler extends DefaultHandler {
        // 定义javabean对象
        private Linkman linkman = null;
        // 定义一个集合封装javabean对象
        private List<Linkman> list = null;
        // 定义解析的元素的名字
        private String name = null;
        @Override
        public void startDocument() throws SAXException {
            super.startDocument();
            // 创建list集合的对象
            this.list = new ArrayList<Linkman>();
        }
        @Override
        public void startElement(String uri, String localName, String name,
                Attributes attributes) throws SAXException {
            super.startElement(uri, localName, name, attributes);
            // 记录解析的元素的名
            this.name = name;
            // 如果是linkman那么创建一个Linkman对象
            if("linkman".equals(this.name)){
                this.linkman = new Linkman();
            }
        }
        @Override
        public void characters(char[] ch, int start, int length)
                throws SAXException {
            super.characters(ch, start, length);
            // 如果此时元素名是name获取文本值
            if("name".equals(this.name)){
                this.linkman.setName(new String(ch,start,length));
            }
            // 如果此时元素名是phone获取文本值
            if("phone".equals(this.name)){
                this.linkman.setPhone(new String(ch,start,length));
            }
            // 如果此时元素名是email获取文本值
            if("email".equals(this.name)){
                this.linkman.setEmail(new String(ch,start,length));
            }
        }
        @Override
        public void endElement(String uri, String localName, String name)
                throws SAXException {
            super.endElement(uri, localName, name);
            // 释放this.name
            this.name = null;
            // 如果此时的元素名是linkman
            if("linkman".equals(name)){
                // 将linkman对象添加到集合
                this.list.add(this.linkman);
                // 清空linkman对象
                this.linkman = null;
            }
        }
        // 对外提供一个获取封装好linkman集合的方法
        public List<Linkman> getList() {
            return list;
        }
    }

    总结:如果使用SAX进行数据的读取那么一定是一个很好的选择,但是该解析技术不能进行其他的操作比如:增、删和改。
    解决方案:可以有一个种技术奖DOM和SAX结合起来即可以高效的查询又可以进行实际的数据操作(增、删和改)。即使用第三方的XML解析技术DOM4J。
    DOM4J解析
    DOM4J即Document Object Model for Java使用java技术以文档方式解析XML数据的模型。
    DOM4J是开源组织提供的一个免费的、强大的XML解析工具,如果开发者需要在项目中使用那么需要下载并引入jar包。
    dom4j is an Open Source XML framework for Java. dom4j allows you to read, write, navigate, create and modify XML documents. dom4j integrates with DOM and SAX and is seamlessly integrated with full XPath support
    下载:http://sourceforge.net/projects/dom4j
    引入:dom4j-1.6.1.jar (核心包)、 jaxen-1.1-beta-6.jar(Xpath支持包)
    (1)如何去学习一个开源的工具包?
    一般的开源工具中都提供了免费的API文件,开发者可以参考该文档。
    DOM4J提供的文档中有一个免费教程可以直接使用。 【Quickstart】
    开始解析
    (1)准备需要解析的xml文件linkmans.xml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <linkmans>
        <linkman>
            <name>jack</name>
            <phone>18663243245</phone>
            <email>jack@163.com</email>
        </linkman>
        <linkman>
            <name>张三</name>
            <phone>1353243247</phone>
            <email>zs@126.com</email>
        </linkman>
    </linkmans>
    2. 获取解析器
    1
    2
    3
    public static SAXReader getReader(){
        return new SAXReader();
    }
    3. 获取解析对象
    1
    2
    3
    4
    5
    6
    7
    public static Document getDocument(File file)throws Exception{
        // 获取解析器
        SAXReader reader = getReader();
        // 解析文档
        Document doc = reader.read(file);
        return doc;
    }
    4. 获取根元素节点
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public static void getRoot(File file)throws Exception{
        // 4.1获取解析器
        SAXReader reader = getReader();
        // 4.2解析文档
        Document doc = reader.read(file);
        // 4.3获取根元素
        Element root = doc.getRootElement();
        System.out.println(root.getName());
    }
    5. 获取指定的其他的元素,获取其他元素的时候默认需要从根节点开始查找。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    public static void getElement(File file) throws Exception {
        // 获取解析器
        SAXReader reader = getReader();
        // 解析文档
        Document doc = reader.read(file);
        // 获取根元素
        Element root = doc.getRootElement();
        // 获取所有的linkman
        List list = root.elements("linkman");
        Iterator it = list.iterator();
        // 循环遍历节点
        while (it.hasNext()) {
            Element ele = (Element) it.next();
            System.out.println(ele.getName());
        }
        System.out.println("---------------");
        // 简化
        for (Iterator i = root.elementIterator(); i.hasNext();) {
            Element element = (Element) i.next();
            System.out.println(element.getName());
        }
        // 获取第二个linkman的名字
        Element linkman2 = (Element) list.get(1);
        String name = linkman2.element("name").getText();
        System.out.println(name);
    }
    6. 添加元素
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    public static Document addElement(File file)throws Exception{
            // 获取解析器
            SAXReader reader = getReader();
            // 解析文档
            Document doc = reader.read(file);
            // 获取根元素
            Element root = doc.getRootElement();
            // 创建新元素
            Element new_linkman = DocumentHelper.createElement("linkman");
            Element new_name = DocumentHelper.createElement("name");
            Element new_phone = DocumentHelper.createElement("phone");
            Element new_email = DocumentHelper.createElement("email");
      
            new_name.setText("焦宁波");
            new_phone.setText("186xxxxxxxxx");
            new_email.setText("jnb@itcast.cn");
            // 建立关系
            new_linkman.add(new_name);
            new_linkman.add(new_phone);
            new_linkman.add(new_email);
            root.add(new_linkman);
            return doc;
        }
    7. 修改的document需要进行持久化的操作,因此需要提供以下的方法,提供一个工具方法将内存中的Document写入XML文件
       
    1
    2
    3
    4
    5
    6
    7
    8
    public static void writeDocument2XML(Document doc, File file)throws Exception{
        // 创建创建一个转换对象。 可以解决输入的数据时中文的乱码问题
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
        // 将doc写入指定文件
        writer.write(doc);
        // 释放资源
        writer.close();
    }
    8. 修改元素
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public static Document modifyElement(File file) throws Exception {
        // 获取解析器
        SAXReader reader = getReader();
        // 解析文档
        Document doc = reader.read(file);
        // 获取根元素
        Element root = doc.getRootElement();
        // 直接获取第二个linkman的name
        Element name =((Element)root.elements("linkman").get(1)).element("name");
        name.setText("李四");
        return doc;
    }
    9. 删除元素
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public static Document removeAll(File file)throws Exception{
        // 获取解析器
        SAXReader reader = getReader();
        // 解析文档
        Document doc = reader.read(file);
        // 获取根元素
        Element root = doc.getRootElement();
        // 获取所有的linkman
        List list = root.elements("linkman");
        // 循环断绝关系
        for(Object temp :list){
           // 转型
           Element linkman = (Element)temp;
           // 断绝关系
           root.remove(linkman);
        }
        return doc;
    }
    10. 属性的操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static Document optionAttribute(File file)throws Exception{
        // 获取解析器
        SAXReader reader = getReader();
        // 解析文档
        Document doc = reader.read(file);
        // 获取根元素
        Element root = doc.getRootElement();
        // 获取所有的linkman
        List list = root.elements("linkman");
        // 循环添加属性
        int count = 0;
        for(Object temp :list){
           // 转型
           Element linkman = (Element)temp;
           // 添加属性
           linkman.add(DocumentHelper.createAttribute(linkman,"id", "00"+(count+1)));
           count++;
        }
     }
    (11)获取焦宁波的id
    1
    2
    3
    4
    5
    6
    7
    8
    Element linkman3 = (Element) list.get(2);
    String value = linkman3.attribute("id").getText();
    System.out.println(value);
    // 修改属性
    linkman3.attribute("id").setText("007");
    // 删除属性
    linkman3.remove(linkman3.attribute("id"));
    return doc;
    问题:阅读以下的代码,并说出以下的代码的缺点。
     获取linkman中的linkman
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static void findQuestion(File file)throws Exception{
        // 10.1获取解析器
        SAXReader reader = getReader();
        // 10.2解析文档
        Document doc = reader.read(file);
        Element inner_name = doc.getRootElement()  // 获取根元素
              .element("linkman")        // 获取第一个linkman元素
              .element("linkman")        // 获取第一个linkman中的第一个linkman元素
              .element("name");             // 获取上面的name元素
        System.out.println(inner_name.getText());
    }
    发现如果需要遍历一个比较深的元素节点,那么需要多次的element()。
    如:存储一个自己的隐私文件需要建立100个文件夹吗?
    那么如果路径比较长需要进行路径访问的方式的优化。
    如果在DOM4J进行解析查找元素可以使用类似Windows中的路径模式来查找元素那么就变得简单且高效。
    如果使用xpath代码可以简化如下:
    1
    2
    3
    4
    5
    6
    7
    8
    public static void findAnswer(File file)throws Exception{
        // 10.1获取解析器
        SAXReader reader = getReader();
        // 10.2解析文档
        Document doc = reader.read(file);
        Element name = (Element)doc.selectSingleNode("/linkmans/linkman[1]/linkman/name");
        System.out.println(name.getText());
    }
    以上的代码可以通过xpath快速的查找指定的元素节点,因此以后在实际的开发中我们如果需要解析XML数据那么就需要DOM4J+Xpath进行联合的处理。
  15. Xpath简介
    Xpath是一个独立的一个路径语言,主要的目的是为了查找路径中的元素。
    那么DOM4J默认支持Xpath的路径查找。
    常用的方法有以下的两种:
    1
    2
    selectNodes(“xpath”)     //查询指定路径的所有的元素
    selectSingleNode(“xpath”)   // 查询指定路径的第一个元素
    常用的Xpath路径写法
    路径
    说明
    /AAA指定从XML文档的根开始写路径
    //BBB指定从整个XML中搜索满足的元素名
    /AAA/CCC/DDD/*指定路径下所有的元素
    //*指定获取所有的元素
    /AAA/BBB[1]指定路径下的第一个元素,一定是以1开始的
    /AAA/BBB[last()]指定路径下的最后一个元素
    //@id 指定要获取的属性元素
    //BBB[@id]指定带属性的元素
    //BBB[@id=‘b1‘]指定属性值的元素
    //BBB[ position() = floor(last() div 2 + 0.5) or position()
    = ceiling(last() div 2 + 0.5)]
    根据计算获取元素

  16. 使用DOM4J+Xpath实现用户登陆和注册
    (1)编写一个用于用户登陆的信息文件users_login.xml
    1
    2
    3
    4
    <?xml version="1.0" encoding="UTF-8"?>
    <users>
      <user name="jack" password="root"/>
    </users>
    (2)登陆的业务方法
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public static User login(String name, String password, File file)
            throws Exception {
        Document doc = getDoc(file);
        Node node = doc.selectSingleNode("/users/user[@name=‘" + name
                + "‘ and @password=‘" + password + "‘]");
        User user = null;
        if (node != null) {
            String name_value = node.valueOf("@name");
            String password_value = node.valueOf("@password");
            user = new User(name_value, password_value);
        }
        return user;
    }
    (3)注册的业务逻辑方法,提供一个业务逻辑存储一个User
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public static void registUser(User user,File file)throws Exception{
        Document doc = getDoc(file);
        Element root = doc.getRootElement();
        Element new_user = DocumentHelper.createElement("user").addAttribute("name", user.getName())
        .addAttribute("password", user.getPassword());
        root.add(new_user);
        // 将document对象持久化到文件
        XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(file),"UTF-8"));
        writer.write(doc);
        writer.close();
    }
  17. DOM VS SAX VS DOM4J+XPATH
    DOM将XML文件以DOM树的方式装载进内存进行解析。Node、 Element、Document、Text、Attr等。
    缺点: 不能解析大数据的XML文件。
    优先: 对于XML可以进行任何操作。
    SAX将XML的解析分为不同的时间段,因此需要创建开发者自己的事件处理器类。
    startDocument()/endDocument  startElement()/endElement()  characater()
    缺点: 只能获取元素。
    优先: 采用事件机制速度快。
    DOM4J+XPATH
    DOM4J+XPATH结合了DOM和SAX各自的优势并摈弃了两者的缺点。
    总结主来一条:优先使用DOM4J+XPATH
  18. 使用DOM存储一个节点,但是xml文件中连同根元素都会消失,就是没有将DOM树写回XML文件。new DomSource(dom)
  19.  在指定的位置之前插入元素,调用insertBefore()方法的时候应该调用的是直接父类的该方法


javaEE学习笔记【03】XML操作

标签:

原文地址:http://www.cnblogs.com/lindongdong/p/4874691.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!