zoukankan      html  css  js  c++  java
  • 解析和操作XML文件

    Dom4j工具

     使用步骤:

    1)导入dom4j的核心包。 dom4j-1.6.1.jar

     2)编写Dom4j读取xml文件代码

    1,Domj4读取xml文件

    ,准备工作:读取整个文档并获取根节点

            //获取document

            SAXReader reader = new SAXReader();

            Document document = reader.read(new File("src/MyXml.xml"));

             //获取根节点

              Element rootElement = document.getRootElement();

     节点:

            Iterator  Element.nodeIterator();  //获取当前标签节点下的所有子节点

     标签:

            Element  Document.getRootElement();  //获取xml文档的根标签         

            Element   ELement.element("标签名") //指定名称的第一个子标签

            Iterator<Element> Element.elementIterator();//获取所有子标签

           List<Element> Element.elements(); //获取所有子标签

      Iterator<Element> Element.elementIterator("标签名");// 指定名称的所有子标签

      List<Element> Element.elements("标签名"); //指定名称的所有子标签                               

    属性:

      String   Element.attributeValue("属性名") //获取指定名称的属性值

      Attribute Element.attribute("属性名");//获取指定名称的属性对象       

      Attribute.getName()  //获取属性名称

      Attibute.getValue()  //获取属性值

      List<Attribute>         Element.attributes();  //获取所有属性对象

      Iterator<Attribute> Element.attibuteIterator(); //获取所有属性对象

    文本:

            Element.getText();  //获取当前标签的文本

      Element.getTextTrim()//获取当前标签的文本,不包含空格

       Element.elementText("标签名") //获取当前标签的指定名称的子标签的文本内容

    例子:

    /**
     * 读取xml文件内容
     * 
     * 读取核心--获取document对象
     *         SAXReader reader = new SAXReader();
            Document document = reader.read(
                File/URL/InputStream/InputSource/Reader object);
     * 
     * 1.获取根节点(标签)    document.getRootElement()
     * 
     * 2.获取子节点    element.nodeIterator(),然后通过迭代器获取子节点
     * 
     * 3.获取标签        
     *         1)获取指定名称的标签        element.element(String elementName);
     *         2)获取当前标签下的指定名称的子标签集合--两种方法获取
     *                 迭代器接收:element.elementIterator(String elementName)
     *                 List接收:element.elements(String elementName)
     *         3)获取当前标签下的所有子标签--两种方法获取(同上)
     *                 迭代器接收:element.elementIterator()
     *                 List接收:element.elements()
     */
    public class Demo {
    
        public static void main(String[] args) {
    
        }
    
        /**
         * 获取文档所有Element(标签)节点,并打印
         */
        @Test
        public void readXML() throws DocumentException {
            //读取文档,获取document对象
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/MyXml.xml"));
            //得到根节点
            Element rootElement = document.getRootElement();
            //获取子节点
            getChildrenNodes(rootElement);
    
        }
    
        //循环获取子节点,并打印其名称
        private void getChildrenNodes(Element element) {
            //打印节点名字
            System.out.println(element.getName());
    
            @SuppressWarnings("unchecked")
            Iterator<Node> iter = element.nodeIterator();
            while (iter.hasNext()) {
                Node node = iter.next();
    
                if (node instanceof Element) {
                    Element e = (Element) node;
                    //递归获取所有子节点
                    getChildrenNodes(e);
                }
            }
    
        }
    
        /**
         * 获取标签
         */
        @Test 
        public void readXML2() throws DocumentException {
    
            //1.读取文档,获取document对象
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/MyXml.xml"));
            
            //2.得到root(根)标签
            Element rootElement = document.getRootElement();
            System.out.println("根标签:" + rootElement.getName());
    
            //3.获得第一个指定名称的子标签
            Element element = rootElement.element("contract");
            System.out.println("第一个contact子标签:" + element.getName());
    //        System.out.println(element.attribute(0).getName() + element.attribute(0).getValue());
            
            
            //4.获取当前标签下的指定名字的子标签
    //        @SuppressWarnings("unchecked")
    //        Iterator<Element> it = rootElement.elementIterator("contract");
    //        System.out.println("含有"contract"的子标签:");
    //        while (it.hasNext()) {
    //            System.out.println(it.next().getName());
    //        }
            @SuppressWarnings("unchecked")
            List<Element> eList = rootElement.elements("contract");
            System.out.println("含有"contract"的子标签:");
            for (Element e : eList) {
                System.out.println(e.getName());
            }
            
            //5.获取当前标签下的所有子标签
    //        @SuppressWarnings("unchecked")
    //        Iterator<Element> iter = element.elementIterator();
    //        System.out.println("所有子标签:");
    //        while (iter.hasNext()) {
    //            Element e = iter.next();
    //            System.out.println(e.getName());
    //        }
            //elementIterator可以,element.elements()方法也可以做到
            @SuppressWarnings("unchecked")
            List<Element> elements = rootElement.elements();
            Iterator<Element> eIter = elements.iterator();
            System.out.println("所有子标签:");
            while (eIter.hasNext()) {
                System.out.println(eIter.next().getName());
            }
            
        }
    
        
        /**
         * 读取属性节点的信息
         * @throws DocumentException 
         */
        @SuppressWarnings("unchecked")
        public void test3() throws DocumentException {
    
            //获取整个xml对象节点
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/MyXml.xml"));
    
            //获取根节点
            Element contact = document.getRootElement().element("contact");
    
    
            //获取指定名称的属性
    //        Attribute attribute = contact.attribute("id");
    //        System.out.println("通过指定名字获取:
    id:" + attribute.getValue() + "
    ");
            String value = contact.attributeValue("id");
            System.out.println("通过指定名字获取:
    id:" + value + "
    ");
            
            //获取所有属性的名称
            Iterator<Attribute> aIter = contact.attributeIterator();
            System.out.println("获取所有属性:");
            while (aIter.hasNext()) {
                Attribute a = aIter.next();
                System.out.println(a.getName() + ":" +a.getValue());
            }
        }
    
        
        /**
         * 获取文本
         * 注意:空格和换行也是文本
         * @throws DocumentException 
         */
        @Test
        public void test4() throws DocumentException {
            
            //获取整个xml对象节点
            SAXReader reader = new SAXReader();
            Document document = reader.read(new File("src/MyXml.xml"));
    
            //获取根节点
            Element contact = document.getRootElement().element("contact");
            
            //打印文本内容
    //        String text = contact.element("name").getText();
    //        String text = contact.element("name").getTextTrim();
            String text = contact.elementText("name");
            String text2 = contact.elementTextTrim("name");
            System.out.println("elementText:" + text);
            System.out.println("elementTextTrim:" + text2);
            
            //空格和换行也是文本,但是getTextTrim可以去掉空格和换行
    //        String text3 = contact.getText().trim();
            String text3 = contact.getTextTrim();
            System.out.println(text3);
        }
        
        
    }

    Dom4j修改xml文档

                 写出内容到xml文档

                                         XMLWriter writer = new XMLWriter(OutputStream, OutputForamt)

                                         wirter.write(Document);

                  修改xml文档的API

                                增加:

                                                   DocumentHelper.createDocument()  增加文档

                                                   addElement("名称")  增加标签

                                                   addAttribute("名称",“值”)  增加属性

                                修改:

                                                   Attribute.setValue("值")  修改属性值

                                                   Element.addAtribute("同名的属性名","值")  修改同名的属性值

                                                   Element.setText("内容")  修改文本内容

                                删除

                                                   Element.detach();  删除标签 

                                                   Attribute.detach();  删除属性

    例子:

    /**
     * XML文档的增删改
     * 
     * 1. 增加--文档,注释,标签,属性,文本
     * 2. 修改--属性,文本
     * 3. 删除--标签,属性
     * @author Administrator
     *
     */
    
    public class Demo2 {
    
        public static void main(String[] args) {
            new Demo2().CRUD();
        }
    
        /**
         * 对XML文件进行增删改
         */
        public void CRUD() {
            //增加
            addXML();
            //修改
            updateXML();
            //删除
            delFromXML();
        }
    
        /**
         * 增加节标签,属性,文本
         */
        public void addXML() {
            //创建新文档
            Document document = DocumentHelper.createDocument();
            //创建注释
            document.addComment("学生信息...");
            //创建根节点
            Element rootElement = document.addElement("Students");
            //创建第一个子节点
            Element child = rootElement.addElement("childElement")
                    .addAttribute("id", "1");
            child.addElement("name").addText("张三");
            child.addElement("sex").addText("男");
            child.addElement("grade").addText("计算机一班");
            child.addElement("address").setText("广州天河");
            //第二个子节点
            Element child2 = rootElement.addElement("childElement")
                    .addAttribute("id", "2");
            child2.addElement("name").addText("李四");
            child2.addElement("sex").addText("女");
            child2.addElement("grade").addText("计算机二班");
            child2.addElement("address").setText("广州深圳");
    
            //覆盖写入文档
            writeToXML(document);
        }
    
        /**
         * 修改属性,文本
         */
        @SuppressWarnings("unchecked")
        public void updateXML() {
            //获取document对象
            Document document = getDocumentFromXML();
            //修改属性节点,把id为1的改成01
            Element rootElement = document.getRootElement();
            Iterator<Element> eIter = rootElement.elementIterator();
            while (eIter.hasNext()) { 
                Element stu = eIter.next();
                Attribute a =  stu.attribute("id");
                if (a != null && a.getValue().equals("1")) {
                    //                stu.addAttribute("id", "01"); 方式一:通过添加相同名字的属性来修改
                    a.setValue("01");
                    //                System.out.println("00000");
                }
    
                if (a != null && a.getValue().equals("2")) {
                    Iterator<Element> iter = stu.elementIterator();
                    while (iter.hasNext()) {
                        Element element = iter.next();
                        if (element.getName().equals("name")) {
                            element.setText("王丽");
                        }
                    }
                }
            }
    
    
            writeToXML(document);
        }
    
        /**
         * 删除属性,标签
         */
        @SuppressWarnings("unchecked")
        public void delFromXML() {
    
            Document document = getDocumentFromXML();
    
            Element rootElement = document.getRootElement();
            //删除属性节点,其id=2
            Iterator<Element> eIter = rootElement.elementIterator();
            while (eIter.hasNext()) { 
                Element stu = eIter.next();
                Attribute a =  stu.attribute("id");
                if (a != null && a.getValue().equals("2")) {
                    a.detach();
                    //删除标签
                    stu.detach();
                }
                
    
            }
    
            writeToXML(document);
            
        }
    
    
        /**
         * 写入文档
         */
        public void writeToXML(Document document) {
    
            try {
                //输出流
                OutputStream out = new FileOutputStream("src/MyXML.xml");
                //输出格式
                OutputFormat format = OutputFormat.createPrettyPrint();
                format.setEncoding("UTF-8");
                //创建XMLWriter对象
                XMLWriter writer = new XMLWriter(out, format);
                writer.write(document);
    
                //关闭流
                out.close();
                writer.close();
    
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
        }
    
        /**
         * 读取文档
         */
        public Document getDocumentFromXML() {
            try {
                SAXReader reader = new SAXReader();
                return reader.read(new File("src/MyXml.xml"));
    
            } catch (DocumentException e) {
                e.printStackTrace();
                System.exit(0);
            }
            return null;
        }
    }

    xPath技术 

                         引入

                                问题:当使用dom4j查询比较深的层次结构的节点(标签,属性,文本),比较麻烦!!!

                        xPath作用

                                    主要是用于快速获取所需的节点对象。

                         在dom4j中如何使用xPath技术

                                         1)导入xPath支持jar包 。  jaxen-1.1-beta-6.jar

                                         2)使用xpath方法

                                                            List<Node>  selectNodes("xpath表达式");   查询多个节点对象

                                                            Node       selectSingleNode("xpath表达式");  查询一个节点对象

                                        

                        xPath语法

                                         /      绝对路径      表示从xml的根位置开始或子元素(一个层次结构)

                                         //     相对路径       表示不分任何层次结构的选择元素。

                                         *      通配符         表示匹配所有元素

                                         []      条件           表示选择什么条件下的元素

                                          @     属性            表示选择属性节点

                                         and     关系          表示条件的与关系(等价于&&)

                                         text()    文本           表示选择文本内容

    例子:

    public class Demo2 {
    
        @SuppressWarnings("unchecked")
        public static void main(String[] args) throws DocumentException {
            
            //获取整个xml对象节点
            Document document = new SAXReader().read(new File("src/MyXml.xml"));
            
            String xPath;
            
            //定义查找规则
            xPath = "/contactList";//根节点
            
            xPath = "//contact";//子节点的两种形式
            xPath = "//contactList/*";
            
            xPath = "//contactList/*/name";//绝对路径和相对论路径查找标签
            xPath = "//contactList//name";
            
            xPath = "//contact[@id]";//获取contact节点
            xPath = "//@id";//获取名字为id的属性
            xPath = "//*[not(@*)]";//获取没有属性的节点
            xPath = "//contact/name[text()='李四']";//获取名字为李四的节点
            xPath = "//contact/name[normalize-space(text())='董十三']";//忽略文本前后的空格,获取名字为董十三的节点
            xPath = "//contact/qq[string-length(text())>7]";//获取QQ号大于七位的标签
            xPath = "//contact/*[string-length(text())>7]";//获取文本大于七位的标签
            xPath = "//contact/*[string-length(name())>4]";//获取标签名大于四位的标签
            
            List<Node> nList = document.selectNodes(xPath);
            for (Node node : nList) {
                System.out.println(node);
            }
        }
        
    }    

    SAX解析

                         4.1回顾DOM解析

                                         DOM解析原理:一次性把xml文档加载进内存,然后在内存中构建Document树。

                                                                               对内存要求比较要。    

                                                            缺点: 不适合读取大容量的xml文件,容易导致内存溢出。

                                                  

                                         SAX解析原理: 加载一点,读取一点,处理一点。对内存要求比较低。

    SAX解析工具  

    SAX解析工具-  Sun公司提供的。内置在jdk中。org.xml.sax.*

                核心的API:

                         SAXParser类: 用于读取和解析xml文件对象

                                              parse(File f, DefaultHandler dh)方法: 解析xml文件

                                                        参数一: File:表示 读取的xml文件。

                                                       参数二: DefaultHandler: SAX事件处理程序。使用DefaultHandler的子类

                  1.创建SAXParser对象 

                  SAXParser parser=SAXParserFactory.newInstance().newSAXParser();

                      2.调用parse方法

                parser.parse(new File("./src/contact.xml"), new MyDefaultHandler());

     [一个类继承class 类名(extends DefaultHandler)  在调用是创建传进去

     

                                         DefaultHandler类的API:

                                                            void startDocument()  :  在读到文档开始时调用

                                                            void endDocument()  :在读到文档结束时调用

                                                            void startElement(String uri, String localName, String qName, Attributes attributes)  :读到开始标签时调用                                    

                                                            void endElement(String uri, String localName, String qName)   :读到结束标签时调用

                                                            void characters(char[] ch, int start, int length)  : 读到文本内容时调用

    例子:

     1 /*
     2  * 需求:把xml文档完整的打印出来
     3  */
     4 public class Demo2 {
     5 
     6     public static void main(String[] args) throws Exception {
     7 
     8         //SAXParser对象
     9         SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
    10         MyDefaultHandler2 dh = new MyDefaultHandler2();
    11         saxParser.parse(new File("src/MyXml.xml"), dh);
    12         System.out.println(dh.getContent());
    13     }
    14 
    15 }
    16 
    17 class MyDefaultHandler2 extends DefaultHandler {
    18 
    19     //读出内容
    20     private StringBuffer sb = new StringBuffer(1000);
    21     //返回内容结果
    22     public String getContent() {
    23         return sb.toString();
    24     }
    25     
    26     @Override
    27     public void startElement(String uri, String localName, String qName,
    28             Attributes attributes) throws SAXException {
    29         sb.append("<" + qName);
    30         
    31         for (int i = 0, len = attributes.getLength(); i < len; i++) {
    32             sb.append(" " + attributes.getQName(i) + "="" 
    33                     + attributes.getValue(i) + """);
    34         }
    35         
    36         sb.append(">");
    37     }
    38     
    39     @Override
    40     public void characters(char[] ch, int start, int length)
    41             throws SAXException {
    42         sb.append(new String(ch, start, length));
    43     }
    44     
    45     @Override
    46     public void endElement(String uri, String localName, String qName)
    47             throws SAXException {
    48         sb.append("</" + qName + ">"); 
    49     }
    50 
    51 }

             ============DOM解析    vs   SAX解析              ========

            

    DOM解析

    SAX解析

    原理: 一次性加载xml文档,不适合大容量的文件读取

    原理: 加载一点,读取一点,处理一点。适合大容量文件的读取

    DOM解析可以任意进行增删改成

    SAX解析只能读取

    DOM解析任意读取任何位置的数据,甚至往回读

    SAX解析只能从上往下,按顺序读取,不能往回读

    DOM解析面向对象的编程方法(Node,Element,Attribute),Java开发者编码比较简单。

    SAX解析基于事件的编程方法。java开发编码相对复杂。

  • 相关阅读:
    bzoj1015星球大战(并查集+离线)
    bzoj1085骑士精神(搜索)
    bzoj1051受欢迎的牛(Tarjan)
    左偏树学习
    hdu1512 Monkey King(并查集,左偏堆)
    左偏树(模板)
    PAT (Basic Level) Practice (中文) 1079 延迟的回文数 (20分) (大数加法)
    PAT (Basic Level) Practice (中文) 1078 字符串压缩与解压 (20分) (字符转数字——栈存放)
    PAT (Basic Level) Practice (中文) 1077 互评成绩计算 (20分) (四舍五入保留整数)
    PAT (Basic Level) Practice (中文) 1076 Wifi密码 (15分)
  • 原文地址:https://www.cnblogs.com/webyyq/p/7497943.html
Copyright © 2011-2022 走看看