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开发编码相对复杂。

  • 相关阅读:
    解决QPainter::drawText修改文字方向
    解决linux环境下qt groupbox 边框不显示问题
    人既然知道努力就可以进步,为什么还是会不努力?
    学会锻炼感悟爱与幸福的能力
    IT人为什么难以拿到高薪?
    在你月薪三千的时候,做月薪八千的事
    哪些人最终能留在北京?
    如何利用数据挖掘进行分析的方法
    查找附近的人
    dapper 操作类封装
  • 原文地址:https://www.cnblogs.com/webyyq/p/7497943.html
Copyright © 2011-2022 走看看