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这个包里定义:
AttributeAttribute定义了XML的属性
BranchBranch为能够包含子节点的节点如XML元素(Element)和文档(Docuemnts)定义了一个公共的行为,
CDATACDATA 定义了XML CDATA 区域
CharacterDataCharacterData是一个标识借口,标识基于字符的节点。如CDATA,Comment, Text.
CommentComment 定义了XML注释的行为
Document定义了XML文档
DocumentTypeDocumentType 定义XML DOCTYPE声明
ElementElement定义XML 元素
ElementHandlerElementHandler定义了 Element 对象的处理器
ElementPath被 ElementHandler 使用,用于取得当前正在处理的路径层次信息
EntityEntity定义 XML entity
NodeNode为所有的dom4j中XML节点定义了多态行为
NodeFilterNodeFilter 定义了在dom4j节点中产生的一个滤镜或谓词的行为(predicate)
ProcessingInstructionProcessingInstruction 定义 XML 处理指令.
TextText 定义XML 文本节点.
VisitorVisitor 用于实现Visitor模式.
XPathXPath 在分析一个字符串后会提供一个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

总结

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

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

 

转载于:https://www.cnblogs.com/ysySelf/p/10186322.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值