• DOM4J解析XML文档、Document对象、节点对象节点对象属性、将文档写入XML文件


    Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM开发的。与JDOM不同的是,dom4j使用接口和抽象的人分离出来而后独立基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性。 

    Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j。

    使用Dom4j开发,需下载dom4j相应的jar文件。

    Document对象

    DOM4j中,获得Document对象的方式有三种:

    1.读取XML文件,获得document对象            

                       SAXReader reader = new SAXReader();
                  Document   document = reader.read(new File("input.xml"));

    2.解析XML形式的文本,得到document对象.

                       String text = "<members></members>";
                  Document document = DocumentHelper.parseText(text);

    3.主动创建document对象.

                      Document document = DocumentHelper.createDocument();
                 //创建根节点

                      Element root = document.addElement("members");

    节点对象

    1.获取文档的根节点.

          Element root = document.getRootElement();

    2.取得某个节点的子节点.

    Element element=node.element(“书名");

    3.取得节点的文字

          String text=node.getText();

    4.取得某节点下所有名为“member”的子节点,并进行遍历.
     List nodes = rootElm.elements("member");
     
      for (Iterator it = nodes.iterator(); it.hasNext();) {
         Element elm = (Element) it.next();
        // do something
     }

    5.对某节点下的所有子节点进行遍历.
        for(Iterator it=root.elementIterator();it.hasNext();){
           Element element = (Element) it.next();
           // do something
        }

    6.在某节点下添加子节点.
    Element ageElm = newMemberElm.addElement("age");

    7.设置节点文字.
     element.setText("29");

    8.删除某节点.
    //childElm是待删除的节点,parentElm是其父节点

        parentElm.remove(childElm);

    9.添加一个CDATA节点.
    Element contentElm = infoElm.addElement("content");
    contentElm.addCDATA(diary.getContent());

    节点对象属性

    1.取得某节点下的某属性
        Element root=document.getRootElement();    
        //属性名name

             Attribute attribute=root.attribute("size");

    2.取得属性的文字
        String text=attribute.getText();

     3.删除某属性
     Attribute attribute=root.attribute("size");
     root.remove(attribute);

    3.遍历某节点的所有属性
       Element root=document.getRootElement();    
       for(Iterator it=root.attributeIterator();it.hasNext();){
             Attribute attribute = (Attribute) it.next();
             String text=attribute.getText();
             System.out.println(text);
        }

    4.设置某节点的属性和文字.
       newMemberElm.addAttribute("name", "sitinspring");

    5.设置属性的文字
       Attribute attribute=root.attribute("name");
       attribute.setText("sitinspring");

    将文档写入XML文件.

    1.文档中全为英文,不设置编码,直接写入的形式.
      XMLWriter writer = new XMLWriter(new  FileWriter("output.xml"));
      writer.write(document);
      writer.close();

    2.文档中含有中文,设置编码格式写入的形式.
    OutputFormat format = OutputFormat.createPrettyPrint();
    // 指定XML编码                   

         format.setEncoding("GBK");       
    XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
    writer.write(document);
    writer.close();

    Dom4j在指定位置插入节点

    1.得到插入位置的节点列表(list)

    2.调用list.add(index,elemnent),由index决定element的插入位置。

    Element元素可以通过DocumentHelper对象得到。示例代码:

    Element aaa = DocumentHelper.createElement("aaa");

    aaa.setText("aaa");

    List list = root.element("书").elements();

    list.add(1, aaa);

    //更新document

    字符串与XML的转换 

    1.将字符串转化为XML
     

         String text = "<members> <member>sitinspring</member></members>";
    Document document = DocumentHelper.parseText(text);

    2.将文档或节点的XML转化为字符串.

         SAXReader reader = new SAXReader();
    Document   document = reader.read(new File("input.xml"));            
    Element root=document.getRootElement();    

                
    String docXmlText=document.asXML();

    String rootXmlText=root.asXML();
    Element memberElm=root.element("member");
    String memberXmlText=memberElm.asXML();
    续写

    dom4j是一个Java的XML API,类似于jdom,用来读写XML文件的。

    下载(环境配置)

    DOM4J是开源组织提供的一个免费的、强大的XML解析工具,如果开发者需要在项目中使用那么需要下载并引入jar包。

    1. 下载DOM4J地址:http://sourceforge.net/projects/dom4j

    2. 引入:dom4j-1.6.1.jar (核心包)、 jaxen-1.1-beta-6.jar(Xpath支持包)

    方法

    它的主要方法都在org.dom4j这个包里定义:
    Attribute Attribute定义了XML的属性
    Branch Branch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,
    CDATA CDATA 定义了XML CDATA 区域
    CharacterData CharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text.
    Comment Comment 定义了XML注释的行为
    Document 定义了XML文档
    DocumentType DocumentType 定义XML DOCTYPE声明
    Element Element定义XML 元素
    ElementHandler ElementHandler定义了 Element 对象的处理器
    ElementPath 被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
    Entity Entity定义 XML entity
    Node Node为所有的dom4j中XML节点定义了多态行为
    NodeFilter NodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
    ProcessingInstruction ProcessingInstruction 定义 XML 处理指令.
    Text Text 定义XML 文本节点.
    Visitor Visitor 用于实现Visitor模式.
    XPath XPath 在分析一个字符串后会提供一个XPath 表达式

    继承关系

    要想弄懂这套接口,关键的是要明白接口的继承关系:
    • interface java.lang.Cloneable
      • interface org.dom4j.Node
      • interface org.dom4j.Attribute
      • interface org.dom4j.Branch
        • interface org.dom4j.Document
        • interface org.dom4j.Element
      • interface org.dom4j.CharacterData
        • interface org.dom4j.CDATA
        • interface org.dom4j.Comment
        • interface org.dom4j.Text
      • interface org.dom4j.DocumentType
      • interface org.dom4j.Entity
      • interface org.dom4j.ProcessingInstruction

    主要JAVA包

    Document对象

    1.读取XML文件,获得document对象.  

    SAXReader reader = new SAXReader();   
    Document   document = reader.read(new File("input.xml"));   
    

    2.解析XML形式的文本,得到document对象.   

    String text = "<members></members>";   
    Document document = DocumentHelper.parseText(text);   
    

    3.主动创建document对象.   

    Document document = DocumentHelper.createDocument();   
    Element root = document.addElement("members");// 创建根节点   
    

    Element节点

    1.获取文档的根节点.   
    Element rootElm = document.getRootElement();   
    2.取得某节点的单个子节点.   

    Element memberElm=root.element("member");// "member"是节点名   

    3.取得节点的文字   

    String text=memberElm.getText();也可以用:   
    String text=root.elementText("name");这个是取得根节点下的name字节点的文字.   

    4.取得某节点下名为"member"的所有字节点并进行遍历.   

    List nodes = rootElm.elements("member");   
    for (Iterator it = nodes.iterator(); it.hasNext();) {   
      Element elm = (Element) it.next();   
      // do something   
    }   

    5.对某节点下的所有子节点进行遍历.   

    for(Iterator it=root.elementIterator();it.hasNext();){   
      Element element = (Element) it.next();   
       // do something   
    }   

    6.在某节点下添加子节点.   

    Element ageElm = newMemberElm.addElement("age");   

    7.设置节点文字.   

    ageElm.setText("29");   

    8.删除某节点.   

    parentElm.remove(childElm);// childElm是待删除的节点,parentElm是其父节点   

    9.添加一个CDATA节点.   

    Element contentElm = infoElm.addElement("content");   
    contentElm.addCDATA(diary.getContent());  

    Attribute属性

    1.取得某节点下的某属性   

    Element root=document.getRootElement();       
    Attribute attribute=root.attribute("size");// 属性名name

    2.取得属性的文字   

    // 也可以用
    String text=attribute.getText();   
    //  这个是取得根节点下name字节点的属性firstname的值:  
    String text2=root.element("name").attributeValue("firstname");

    3.遍历某节点的所有属性    

    Element root=document.getRootElement();        
    for(Iterator it=root.attributeIterator();it.hasNext();){    
     Attribute attribute = (Attribute) it.next();    
     String text=attribute.getText();    
     System.out.println(text);    
    }

    4.设置某节点的属性和文字.    

    newMemberElm.addAttribute("name", "sitinspring");    

    5.设置属性的文字   

    Attribute attribute=root.attribute("name");    
    attribute.setText("sitinspring");    

    6.删除某属性    

    Attribute attribute=root.attribute("size");// 属性名name    
    root.remove(attribute);    

    解析步骤

    1. 准备需要解析的xml文件linkmans.xml

    <?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. 获取解析器

    public static SAXReader getReader() {
        return new SAXReader();
    }
    

    3. 获取解析对象

    public static Document getDocument(File file) throws Exception {
        // 3.1获取解析器
        SAXReader reader = getReader();
        // 3.2解析文档
        Document doc = reader.read(file);
        return doc;
    }
    

    4. 获取根元素节点

    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. 获取指定的其他的元素

    public static void getElement(File file) throws Exception {
        // 5.1获取解析器
        SAXReader reader = getReader();
        // 5.2解析文档
        Document doc = reader.read(file);
        // 5.3获取根元素
        Element root = doc.getRootElement();
        // 5.4获取所有的linkman
        List list = root.elements("linkman");
        Iterator it = list.iterator();
        // 5.5循环遍历节点
        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());
        }
        // 5.6获取第二个linkman的名字
        Element linkman2 = (Element) list.get(1);
        String name = linkman2.element("name").getText();
        System.out.println(name);
    }
    

    6. 添加元素

    public static Document addElement(File file) throws Exception {
        // 6.1获取解析器
        SAXReader reader = getReader();
        // 6.2解析文档
        Document doc = reader.read(file);
        // 6.3获取根元素
        Element root = doc.getRootElement();
        // 6.4创建新元素
        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");
        // 6.5建立关系
        new_linkman.add(new_name);
        new_linkman.add(new_phone);
        new_linkman.add(new_email);
        root.add(new_linkman);
        return doc;
    }
    

    7. 修改的document需要进行持久化的操作,因此需要提供以下的方法。

    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. 修改元素

    public static Document modifyElement(File file) throws Exception {
        // 8.1获取解析器
        SAXReader reader = getReader();
        // 8.2解析文档
        Document doc = reader.read(file);
        // 8.3获取根元素
        Element root = doc.getRootElement();
        // 8.4直接获取第二个linkman的name
        Element name = ((Element) root.elements("linkman").get(1)).element("name");
        name.setText("李四");
        return doc;
    }
    

    9. 删除元素

    public static Document removeAll(File file) throws Exception {
        // 9.1获取解析器
        SAXReader reader = getReader();
        // 9.2解析文档
        Document doc = reader.read(file);
        // 9.3获取根元素
        Element root = doc.getRootElement();
        // 9.4获取所有的linkman
        List list = root.elements("linkman");
        // 9.4循环断绝关系
        for (Object temp: list) {
            // 转型
            Element linkman = (Element) temp;
            // 断绝关系
            root.remove(linkman);
        }
        return doc;
    }
    

    10. 属性的操作

    public static Document optionAttribute(File file) throws Exception {
        // 10.1获取解析器
        SAXReader reader = getReader();
        // 10.2解析文档
        Document doc = reader.read(file);
        // 10.3获取根元素
        Element root = doc.getRootElement();
        // 10.4获取所有的linkman
        List list = root.elements("linkman");
        // 10.4循环添加属性
        int count = 0;
        for (Object temp: list) {
            // 转型
            Element linkman = (Element) temp;
            // 添加属性
            linkman.add(DocumentHelper.createAttribute(linkman, "id", "00" + (count + 1)));
            count++;
        }
        // 10.5获取焦宁波的id
        Element linkman3 = (Element) list.get(2);
        String value = linkman3.attribute("id").getText();
        System.out.println(value);
        // 10.6修改属性
        linkman3.attribute("id").setText("007");
        // 10.7删除属性
        linkman3.remove(linkman3.attribute("id"));
        return doc;
    }

    11.

          Element rootElement = document.getRootElement(); //获取文档的根节点<Package>/<Package>
         Element element = rootElement.element("RequestNodes");//获取父节点(RequestNodes)
         List elements = element.elements("RequestNode"); //获取所有的 RequestNode节点

          Iterator it = elements.iterator();
         while (it.hasNext()) {
         Element ele = (Element) it.next();
         Element elementZipCode= ele.element("ZipCode");//获取到每个邮编节点
         String text = elementZipCode.getText();//邮编得的值

    }

       例子:xml  

    ?xml version="1.0" encoding="GBK"?>
    <Package>
    <Head>
    <TransDate>2017-05-12</TransDate>
    <TransTime>15:27:05</TransTime>
    <TransName>PR*****</TransName>
    </Head>
    <RequestNodes>
    <RequestNode>
    <AppntName>*****</AppntName>
    <ZipCode>20*****</ZipCode>
    <Address>*****</Address>
    <ContNo>2016051100111486</ContNo>
    <CValiDate>2016-05-12</CValiDate>
    <PaytoDate>2017-05-12</PaytoDate>
    <InsuredName>王丽</InsuredName>
    <AgentName>功夫熊猫</AgentName>
    <Phone>1******838738</Phone>
    <PayMode>*****</PayMode>
    <HLPrem>0.00</HLPrem>
    <Risks>
    <Risk>
    <RiskName>*********</RiskName>
    <Premium>10000.00</Premium>
    <SubRiskFlag>M</SubRiskFlag>
    </Risk>
    </Risks>
    <BankCode>*****</BankCode>
    <AccType>******</AccType>
    <BankAccNo>***************0799</BankAccNo>
    <SumPremium>1*****0.00</SumPremium>
    <ComAddress>*****</ComAddress>
    <NoticeNo>500*****00*****32</NoticeNo>
    <PrintDate>*****-05-12</PrintDate>
    </RequestNode>
    </RequestNodes>
    </Package>

    例子

    //需要解析的emplist.xml
    <?xml version="1.0" encoding="utf-8"?>
    <list> 
      <emp id="1"> 
        <name>张三</name>  
        <age>34</age>  
        <gender>男</gender>  
        <salary>3000</salary> 
      </emp>  
      <emp id="2"> 
        <name>李四</name>  
        <age>14</age>  
        <gender>女</gender>  
        <salary>4000</salary> 
      </emp>  
      <emp id="3"> 
        <name>王五</name>  
        <age>14</age>  
        <gender>女</gender>  
        <salary>50000</salary> 
      </emp>  
      <emp id="4"> 
        <name>赵六</name>  
        <age>29</age>  
        <gender>男</gender>  
        <salary>300</salary> 
      </emp>  
      <emp id="5"> 
        <name>钱7</name>  
        <age>53</age>  
        <gender>男</gender>  
        <salary>12000</salary> 
      </emp> 
    </list>
    
    /**
     * 该类用于表示emplist.xml文档中的一个emp数据
     */
    public class Emp {
        private int id;
        private String name;
        private int age;
        private String gender;
        private int salary;
        public Emp(){
            
        }
        public Emp(int id, String name, int age, String gender, int salary) {
            super();
            this.id = id;
            this.name = name;
            this.age = age;
            this.gender = gender;
            this.salary = salary;
        }
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public int getAge() {
            return age;
        }
        public void setAge(int age) {
            this.age = age;
        }
        public String getGender() {
            return gender;
        }
        public void setGender(String gender) {
            this.gender = gender;
        }
        public int getSalary() {
            return salary;
        }
        public void setSalary(int salary) {
            this.salary = salary;
        }
        
        public String toString(){
            return  id+","+name+","+age+","+gender+","+salary;
        }
    }
    
    /**
     * 使用DOM解析XML文档
     */
    public class ParseXmlDemo {
        public static void main(String[] args) {
            try {
                /**
                 * 解析大致步骤:
                 * 1:创建SAXReader
                 * 2:使用SAXReader解析指定的xml文档信息,并返回对应Document对象
                 *      Document对象中就包含了该XML文档中的所有信息及结构了。
                 * 3:根据文档结构将xml描述的树状信息读取到。
                 */
                //1:
                SAXReader reader = new SAXReader();
                /**
                 * 2:解析xml工作在这里就进行完毕了
                 * 
                 */
                Document doc =    reader.read(new File("emplist.xml"));
                //3
                List<Emp> list = new ArrayList<Emp>();
                    /**
                     * 解析第一步,获取根标签(根元素)
                     * Document提供了一个可以获取根元素的方法;
                     * Element getRootElement();
                     * Element 的每一个实例表示xml文档中一对标签。这里获取的根标签就相当于是
                     * <list>....</list>那对标签。
                     */
                Element root =doc.getRootElement();
                /**
                 * 由于xml文档中一个标签可能含有其他子标签
                 * 所以Element对象提供了可以获取其表示的标签中的子标签的方法:
                 * List elment()
                 * 获取当期标签下所有子标签,List集合中存放的是若干个Element实例,
                 * 每个实例表示其中一个子标签。
                 * 
                 * List elements(String name)
                 * 获取当前标签下所有同名(参数指定该名字)子标签
                 * 
                 *  Element element(String name)
                 *  获取当前标签下给定名字的标签,若有多个,获取第一个。
                 */
                
                List<Element>  elementlist = root.elements("emp");
                //遍历每一个<emp>标签
                
                for(Element empEle: elementlist){
                    //获取name的值
                    Element nameEle = empEle.element("name");
                    /**
                     * String getText()  获取当前标签中间的文本(字符串)
                     * getTextTrim()  去空白。。
                     */
                    String name =nameEle.getText();
                    
                    Element ageEle =empEle.element("age");
                    int  age = Integer.parseInt(ageEle.getText());
                    /**
                     * String elmentText(String name)
                     * 获取当前标签下给定名字的子标签中间的文本,这个方法等同于上面获取name中间文本的两句代码。
                     */
                    String gender =empEle.elementText("gender");
                    
                    int salary=Integer.parseInt(empEle.elementText("salary"));
                    
                    /**
                     * Element 还提供了可以用来获取其描述的标签中的属性信息:
                     * Attribute attribute(String name)
                     * 该方法可以获取给定名字的属性,Attribute的每一个实例都可以表示一个标签中的一个属性。
                     */
                    Attribute attr =empEle.attribute("id");
                    
                    int id =Integer.parseInt(attr.getValue());
                    
                    Emp emp = new Emp(id,name,age,gender,salary);
                    
                    list.add(emp);
                }
                System.out.println("解析完毕!");
                for(Emp e :list){
                    System.out.println(e);
                }
                
            
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    

    运行结果:

    解析完毕!
    1,张三,34,男,3000
    2,李四,14,女,4000
    3,王五,14,女,50000
    4,赵六,29,男,300
    5,钱7,53,男,12000


    循环获取xml数据
    <Body>
      <getSmsSentResultResponse ns2="http://services.cfx.smpin.tydic.com/">
        <return>
          <data>
            <businessId>100000182</businessId>
            <businessName>****</businessName>
            <deliverFlag>2</deliverFlag>
            <lantId>931</lantId>
            <receivePhone>10001</receivePhone>
            <sendContent>*****</sendContent>
            <sendPhone>1890*****</sendPhone>
            <sendTime>2020-04-03T16:35:42+08:00</sendTime>
            <status>0</status>
            <sysCode>*****</sysCode>
          </data>
          <data>
            <businessId>3200050</businessId>
            <businessName>******</businessName>
            <deliverFlag>2</deliverFlag>
            <lantId>931</lantId>
            <receivePhone>10001322</receivePhone>
            <sendContent>****</sendContent>
            <sendPhone>1890*****</sendPhone>
            <sendTime>2020-04-03T14:58:50+08:00</sendTime>
            <status>0</status>
            <sysCode>****</sysCode>
          </data>
          <result>0</result>
          <resultDesc>成功</resultDesc>
        </return>
      </getSmsSentResultResponse>
    </Body>
    serviceRetInfoDto = invokeService.orderInvokeInterface("getrechargeMessage", reMap, null);
                String hasOpenSheet= serviceRetInfoDto.getRetString();
                String flag="1";
                if("1".equals(serviceRetInfoDto.getSuccessFlag())){
                    Document document = DocumentHelper.parseText(hasOpenSheet);
                    List<Element> selectNodes = document.selectNodes("/result/data");
                    if(selectNodes.size()>0){
                        for(int i=0;i<selectNodes.size();i++){
                            String businessId = selectNodes.get(i).selectSingleNode("businessId").getText();
                            if("100000182".equals(businessId)){
                                flag="0";
                                break;
                            }
                        }
                    }
                    if(flag=="0"){
                        map.put("flag", "0");
                    }else{
                        map.put("flag", "1");
                    }
                }

    总结

    1. dom4j是一个易用的、开源的库,用于XML,XPath和XSLT。它应用于Java平台,采用了Java集合框架并完全支持DOM,SAX和JAXP。

    2. dom4j是一个非常非常优秀的Java XML API,具有性能优异、功能强大和极端易用使用的特点,同时它也是一个开放源代码的软件,现在越来越多的Java软件都在使用dom4j来读写XML,特别值得一提的是连Sun的JAXM也在用dom4j。

  • 相关阅读:
    三个Bootstrap免费字体和图标库
    前端实时消息提示的效果-websocket长轮询
    带分页的标签
    VMware-workstation安装
    摄影/肥猫的大头贴
    Smith Numbers(分解质因数)
    C
    B
    Ball
    Property Distribution(DFS)
  • 原文地址:https://www.cnblogs.com/xiaotang5051729/p/13213884.html
Copyright © 2020-2023  润新知