当前位置: 代码网 > it编程>编程语言>Java > java中XML的使用全过程

java中XML的使用全过程

2025年05月21日 Java 我要评论
什么是xmlxml(extensible markup language),可扩展标记语言,是一种简单的基于文本的语言,旨在以村文本格式存储和传输数据,他代表可扩展标记语言。1、作为系统的配置文件2、

什么是xml

xml(extensible markup language),可扩展标记语言,是一种简单的基于文本的语言,旨在以村文本格式存储和传输数据,他代表可扩展标记语言。

  • 1、作为系统的配置文件
  • 2、作为一种特殊的数据结构,在网络中进行传输

特点

xml与操作系统、编程语言的开发平台无关

实现不同系统之间的数据交换

xml作用

  • 数据交互
  • 配置应用程序和网站
  • ajax基石

xml的编写语法

基本语法

  • 所有xml元素都必须有结束标签
  • xml标签对大小写敏感
  • xml必须正确的嵌套
  • 同级标签以缩进对齐
  • 元素名称可以包含字母、数字或其他的字符
  • 元素名称不能以数字或者标点符号开始
  • 元素名称中不能含空格
<?xml version="1.0" encoding="utf-8"?>
<books>
    <!--图书信息  这是注释-->
    <book id="bk101">
        <author>王珊</author>
        <title>.net高级编程</title>
        <description>包含c#框架和网络编程等</description>
    </book>
    <book id="bk102">
        <author>李明明</author>
        <title>xml基础编程</title>
        <description>包含xml基础概念和基本作用</description>
    </book>
</books>

注意一:<?xml version="1.0" encoding="utf-8" ?>这行是必须要写的,且必须放在首行(前面有注释都不行)。表示版本为1.0,以utf-8字符集来编码

  • 注意二:根标签只能有一个,子标签可以有多个
  • 注意三:标签是成对存在的,记得嵌套正确

xml文件可以在浏览器中查看,我们打开浏览器看到,我们写的特殊字符的格式是我们所预期的

特殊字符编写

1、 指定字符替代特殊字符

xml中书写”<’

“&”等,可能会出现冲突,导致报错,此时可以用如下特殊字符替代。

指定字符特殊字符含义
&lt;<小于
&gt;>大于
&amp;&小于
&apos;单引号
&quot;"双引号

2、cdata的数据区

xml中可以写一个叫cdata的数据区:<![cdata[..内容... ]]>,里面的内容可以随便写

<users>
    <user id="1">
        <name>张三</name>
        <age>18</age>
        <address>广州</address>
    </user>
    <userattribute>都是爱学习的人</userattribute>
    <user id="2">
        <name>李四</name>
        <age>25</age>
        <address>哈尔滨</address>
    </user>

    <!--以下是带有大于号小于号等特殊字符的写法-->
    <special>
        <![cdata[
            5 > 2 && 3 < 5
        ]]>

    </special>
    <!--特殊字符用法二-->
    <special>  5 &gt; 2 &amp;&amp; 3 &lt; 5 </special>
</users>

约束xml的书写格式

dtd文档

特点

  • 可以约束xml文件的编写
  • 不能约束具体的数据类型

dtd文档的使用

①:编写dtd约束文档,后缀必须是.dtd

data.dtd

根目录只能叫做书并且可以有多个书的子元素

书只能由书名作者售价构成

<!element 书架 (书+)>
<!element 书 (书名,作者,售价)>
<!element 书名 (#pcdata)>
<!element 作者 (#pcdata)>
<!element 售价 (#pcdata)>

②:在需要编写的xml文件中导入该dtd约束文档
 

<!doctype 书架 system "data.dtd">

③:然后xml文件,就必须按照dtd约束文档指定的格式进行编写,否则报错

<?xml version="1.0" encoding="utf-8"?>
<!-- 导入约束格式 -->
<!doctype 书架 system "data.dtd">
<书架>
	<!-- 只能这么写否则报错 -->
    <书>
        <书名>哈利波特</书名>
        <作者>j.k.罗琳</作者>
        <!-- 售价的类型可以是浮点型,字符串,也可以是任何数据类型 -->
        <售价>49.9</售价>
    </书>
    <书>
        <书名>西游记</书名>
        <作者>吴承恩</作者>
        <售价>49.9</售价>
    </书>
</书架>

schema文档

特点

  • 可以约束xml文件的编写
  • 可以约束具体的数据类型

schema文档的使用

1、编写schema约束文档,后缀必须是.xsd,具体的形式到代码中观看。

2、在需要编写的xml文件中导入该schema约束文档

3、按照约束内容编写xml文件的标签

<?xml version="1.0" encoding="utf-8"?>
<!-- xmlns: 核心命名空间声明 -->
<!-- xmlns="http://www.w3.org/2001/xmlschema:
声明使用w3c xml schema规范作为默认命名空间,所有未加前缀的标签均属于该规范。 -->
<!-- targetnamespace(目标命名空间): 申明约束文档的地址(命名空间) 这里的data.xsd也是被约束的 -->
<!-- elementformdefault(元素命名空间规则): 先不用管,这是关于局部元素的命名空间归属的属性-->
<schema xmlns="http://www.w3.org/2001/xmlschema"
        targetnamespace="http://www.itcast.cn"
        elementformdefault="qualified" >
<!--全局元素定义,作为根元素,该元素直接属于targetnamespace命名空间-->
    <element name="书架">
        <complextype>
            <!-- maxoccurs="unbounded" 书架下的子元素可以有无穷多个 -->
            <sequence maxoccurs="unbounded">
                <element name="书">
                    <!--  写子元素  -->
                    <complextype>
                        <sequence>
                            <element name="书名" type="string"/>
                            <element name="作者" type="string"/>
                            <element name="价格" type="double"/>
                        </sequence>
                    </complextype>
                </element>
            </sequence>
        </complextype>
    </element>
</schema>

属性命名空间

<?xml version="1.0" encoding="utf-8"?>
<batchcompany xmlns="http://www.aptech_edu.ac"
    xmlns:tea="http://www.tea.org">
    <batch-list>
   	 	<!-- 下面这个命名空间属于xmlns:tea="http://www.aptech_edu.ac" -->
        <batch type="thirdbatch">第三批次</batch>
        <!-- 下面这个命名空间属于xmlns:tea="http://www.tea.org" -->
        <batch tea:type="thirdbatch">第三批茶</batch>
        <!-- 下面这个命名空间属于xmlns:tea="http://www.aptech_edu.ac" -->
        <batch>午班批次</batch>
    </batch-list>
</batchcompany>

除非带有前缀,否则属性属于所属的元素的命名空间

xml命名空间的作用

解决在复杂、大型xml文件中,出现名称相同,但是含义不同的元素

<?xml version="1.0" encoding="utf-8"?>

<!-- 两个厂家(佳能相机和尼康相机)的地址 -->
<cameras xmlns:canon="http://www.canon"
    xmlns:nikon="http://www.nikon.com">
    <!-- 虽然都是相机camera  
    但是第一个是canon(佳能牌)的相机 
    第二个是nikon(尼康牌)的相机 
    -->
    <canon:camera prodid="p663" name="camera傻瓜相机"/>
    <nikon:camera prodid=“k29b3” name=“camera超级35毫米相机"/>
</cameras>

解析xml的方法

本节分三块

dom(内置解析xml)

  1. 基于xml文档树结构的解析
  2. 适用于多次访问的xml文档
  3. 特点:比较消耗资源

sax(内置解析xml)

  1. 基于事件的解析
  2. 适用于大数据量的xml文档
  3. 特点:占用资源少,内存消耗小

dom4j

  1. 非常优秀的java xml api
  2. 性能优异、功能强大
  3. 开放源代码

​​dom解析xml

基于xml文档树结构的解析

适用于多次访问的xml文档

特点:比较消耗资源

dom介绍

文档对象模型(document object model)

dom把xml文档映射成一个倒挂的树

dom解析包:org.w3c.dom

org.w3c.dom​​ 是 java 中用于处理 ​​文档对象模型(dom)​​ 的核心包,由 ​​万维网联盟(w3c)​​ 制定并维护。它是 w3c dom 标准的 java 语言绑定实现,主要用于解析、访问和操作 xml/html 文档的结构化内容。(jdk自带的用于解析xml文件的api)

常用接口

常用接口常用方法说明
document:表示整个 xml 文档nodelist getelementsbytagname(string tag)按文档顺序返回文档中指定标记名称的所有元素集合
element createelement(string tagname)创建指定标记名称的元素
node:该文档树中的单个节点nodelist getchildnodes()获取该元素的所有子节点,返回节点集合
element:xml 文档中的一个元素string gettagname()获取元素名称

dom解析包的使用

dom解析xml文件步骤

  1. 创建解析器工厂对象
  2. 解析器工厂对象创建解析器对象
  3. 解析器对象指定xml文件创建document对象
  4. 以document对象为起点操作dom树
<?xml version="1.0" encoding="utf-8"?>
<phoneinfo>
    <brand name="华为">
        <type name="u8650"/>
        <type name="hw123"/>
        <type name="hw321"/>
    </brand>
    <brand name="苹果">
        <type name="iphone4"/>
    </brand>
</phoneinfo>

显示phoneinfo.xml文件中收藏的手机品牌和型号

package com.hsh.exercise2;

import org.w3c.dom.document;
import org.w3c.dom.element;
import org.w3c.dom.nodelist;

import javax.xml.parsers.documentbuilder;
import javax.xml.parsers.documentbuilderfactory;

public class main {
    public static void main(string[] args) throws exception {
        // 创建解析器工厂对象
        documentbuilderfactory factory = documentbuilderfactory.newinstance();
        // 解析器工厂对象创建解析器对象
        documentbuilder db = factory.newdocumentbuilder();
        // 解析 xml 文件
        document document = db.parse("./src/com/hsh/exercise2/phoneinfo.xml");

        // 获取根元素
        element root = document.getdocumentelement();
        // 获取所有 brand 元素
        nodelist brandlist = root.getelementsbytagname("brand");

        // 遍历每个 brand 节点并打印 name 属性
        for (int i = 0; i < brandlist.getlength(); i++) {
            // 获取 brand 元素
            element brand = (element) brandlist.item(i);
            // 获取节点名称
            system.out.print(brand.getnodename()+":  ");
            // 获取 name 属性
            system.out.print(brand.getattribute("name")+",");
            // 获取节点文本内容  由于是单标签所以为空。
            // system.out.println(brand.gettextcontent());
            // 获取brand 元素下面的 type 元素
            nodelist typelists = brand.getelementsbytagname("type");
            for (int j = 0; j < typelists.getlength(); j++) {
                // 获取 type 元素
                element type = (element) typelists.item(j);
                // 获取节点名称
                system.out.print(type.getnodename()+":  ");
                // 获取 name 属性
                system.out.print(type.getattribute("name")+" ");
            }
            system.out.println();
        }
        // 输出结果
        // brand:  华为,type:  u8650 type:  hw123 type:  hw321 
        // brand:  苹果,type:  iphone4
    }
}

保存xml文件

步骤

  1. 获得transformerfactory对象
  2. 创建transformer对象
  3. 创建domsource对象:包含xml信息
  4. 设置输出属性:编码格式
  5. 创建streamresult对象:包含保存文件的信息
  6. 将xml保存到指定文件中
package com.hsh.exercise3;

import org.w3c.dom.document;
import org.w3c.dom.element;
import org.w3c.dom.bootstrap.domimplementationregistry;
import org.w3c.dom.ls.domimplementationls;

import javax.xml.parsers.documentbuilder;
import javax.xml.parsers.documentbuilderfactory;
import javax.xml.transform.outputkeys;
import javax.xml.transform.transformer;
import javax.xml.transform.transformerfactory;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;

public class main {
    public static void main(string[] args) throws exception {
        //1. 创建工厂transformerfactory对象
        transformerfactory factory = transformerfactory.newinstance();
        //2. 创建transformer对象
        transformer  transformer = factory.newtransformer();

        // 3. 创建document对象来创建新的xml文件,给xml文件设置内容,并将dom结构添加到domsource对象
        // 3.1 创建document对象
        documentbuilderfactory documentfactory = documentbuilderfactory.newinstance();
        documentbuilder  builder = documentfactory.newdocumentbuilder();
        document document = builder.newdocument();

        // 3.2 创建xml结构(即给xml文件设置内容)
        // 创建根元素
        element root = document.createelement("root");
        // 加入到document中
        document.appendchild(root);
        // 创建子元素
        element child = document.createelement("child");
        // 设置属性名和属性值
        child.setattribute("name", "hsh");
        // 设置元素内容
        child.appendchild(document.createtextnode("text content"));
        //加入根节点树中
        root.appendchild(child);

        // 3.3 将文件添加到domsource对象中
        domsource source = new domsource(document);


        // 4. 给第二步 的transformer对象设置输出属性
        // 4.1设置是否再xml中添加缩进
        transformer.setoutputproperty(outputkeys.indent,"yes");
        // 4.2指定输出方法
        transformer.setoutputproperty(outputkeys.method, "xml");
        // 4.3指定输出文件编码
        transformer.setoutputproperty(outputkeys.encoding, "utf-8");
        // 5. 创建streamresult对象,指定输出文件 streamresult对象包含了文件信息
        streamresult result = new streamresult("./src/com/hsh/exercise3/collection.xml");

        // 6. 将domsource对象和streamresult对象作为参数传递给transformer对象的transform方法进行保存
        transformer.transform(source, result);
        system.out.println("保存成功!");
    }
}

保存后的文件如下

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<root>
    <child name="hsh">text content</child>
</root>

添加dom节点

添加手机收藏

  1. 添加新的brand:三星
  2. 给brand节点添加新的子标签type:note4
  3. 将brand添加到dom树中

练习:给手机收藏信息xml中添加新的手机信息,并将手机收藏信息保存到新文件中

添加新的brand:三星

给brand节点添加新的子标签type:note4

将brand添加到dom树中

package com.hsh.exercise3;

import org.w3c.dom.document;
import org.w3c.dom.element;


import javax.xml.parsers.documentbuilder;
import javax.xml.parsers.documentbuilderfactory;
import javax.xml.transform.outputkeys;
import javax.xml.transform.transformer;
import javax.xml.transform.transformerfactory;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;

public class main {
    public static void main(string[] args) throws exception {
        // 创建解析器工厂对象
        documentbuilderfactory  factory = documentbuilderfactory.newinstance();
        documentbuilder db = factory.newdocumentbuilder();
        document document = db.parse("./src/com/hsh/exercise3/收藏信息.xml");

        // 获取根元素
        element root = document.getdocumentelement();
        system.out.println(root.getnodename());

        // 给根元素添加子元素brand
        element brand = document.createelement("brand");
        brand.setattribute("name","三星");
        // 给brand 元素添加子元素type
        element type = document.createelement("type");
        // 设置type的属性
        type.setattribute("name","note4");
        // 将type添加到brand中
        brand.appendchild(type);
        root.appendchild(brand);

        // 创建工厂进行保存
        transformerfactory transformerfactory = transformerfactory.newinstance();
        transformer transformer = transformerfactory.newtransformer();
        // 设置格式化
        // 缩进
        transformer.setoutputproperty(outputkeys.indent, "yes");

        // 指定输出
        transformer.setoutputproperty(outputkeys.method, "xml");
        // 指定编码
        transformer.setoutputproperty(outputkeys.encoding, "gb2312");
        domsource domsource = new domsource(document);
        streamresult streamresult = new streamresult("./src/com/hsh/exercise3/收藏信息.xml");
        transformer.transform(domsource, streamresult);
        system.out.println("保存成功");
    }
}

修改/删除dom节点

给所有的brand标签添加id属性

  • 获取brand标签
  • 调用setattribute()方法添加属性

删除brand值为“华为”的标签

  • getelementsbytagname()方法获取brand标签列表
  • 获得brand值为“华为”的标签对象
  • 通过getparentnode()方法获得父节点对象
  • 调用父节点的removechild()方法删除节点
<?xml version="1.0" encoding="gb2312"?>
<phoneinfo>
    <brand name="华为">
        <type name="u8650"/>
        <type name="hw123"/>  
        <type name="hw321"/>
    </brand>
    <brand name="苹果">   
        <type name="iphone4"/>
    </brand>
    <brand name="三星">         
        <type name="note4"/>  
    </brand>
</phoneinfo>
package com.hsh.exercise4;

import org.w3c.dom.document;
import org.w3c.dom.element;
import org.w3c.dom.nodelist;

import javax.xml.parsers.documentbuilder;
import javax.xml.parsers.documentbuilderfactory;
import javax.xml.transform.outputkeys;
import javax.xml.transform.transformer;
import javax.xml.transform.transformerfactory;
import javax.xml.transform.dom.domsource;
import javax.xml.transform.stream.streamresult;

public class main {
    public static void main(string[] args) throws exception {
        // 创建解析器工厂对象
        documentbuilderfactory  factory = documentbuilderfactory.newinstance();
        documentbuilder db = factory.newdocumentbuilder();
        document document = db.parse("./src/com/hsh/exercise4/收藏信息.xml");

        // 获取根元素
        element root = document.getdocumentelement();
        system.out.println(root.getnodename());
        //  获取root所有brand子级标签
        nodelist nodelist = root.getelementsbytagname("brand");
        for (int i = 0; i < nodelist.getlength(); i++) {
            // 给每一个brand标签加属性
            element brand = (element) nodelist.item(i);
            brand.setattribute("id", (i+1)+"");
        }

        // 遍历子级标签删除 brand的属性为华为的标签
        for (int i = 0; i < nodelist.getlength(); i++) {
            element brand = (element) nodelist.item(i);
            if (brand.getattribute("name").equals("华为")) {
                // 得到父元素
                element parent = (element) brand.getparentnode();
                // 删除
                parent.removechild(brand);
            }
        }
        
        // 创建工厂进行保存
        transformerfactory transformerfactory = transformerfactory.newinstance();
        transformer transformer = transformerfactory.newtransformer();
        // 设置格式化
        // 缩进
        transformer.setoutputproperty(outputkeys.indent, "yes");

        // 指定输出
        transformer.setoutputproperty(outputkeys.method, "xml");
        // 指定编码
        transformer.setoutputproperty(outputkeys.encoding, "gb2312");
        domsource domsource = new domsource(document);
        streamresult streamresult = new streamresult("./src/com/hsh/exercise4/收藏信息.xml");
        transformer.transform(domsource, streamresult);
        system.out.println("保存成功");
    }
}

结果如下。

<?xml version="1.0" encoding="gb2312" standalone="no"?>
<phoneinfo>
        
    
    <brand id="2" name="苹果">
                
        <type name="iphone4"/>
            
    </brand>
        
    <brand id="3" name="三星">
                
        <type name="note4"/>
            
    </brand>
    
</phoneinfo>

sax

基于事件的解析

适用于大数据量的xml文档

特点:占用资源少,内存消耗小

dom4j

优点

  • 非常优秀的java xml api
  • 性能优异、功能强大

开放源代码

  • document:定义xml文档
  • element:定义xml元素
  • text:定义xml文本节点
  • attribute:定义了xml 的属性

dom4j下载和导入项目

1、下载相关jar包

方法一:去dom4j官网

2、将下载的jar包导入到idea项目中去

3、将jar包添加到库中

点击确定,打开lib出现如下界面就说明添加成功。

dom4j代码编写

获取所有值

解析器的构造方法

构造方法说明
public saxreader()xml解析器对象

解析器对象中的方法

方法说明
public document read(string systemid)读取xml文件

document类中的方法

方法说明
element getrootelement();获取根元素对象
public string getname()获取元素标签名
public string attributevalue(qname qname)获取元素的属性名
public string gettext()获取元素的内容
public list<element> elements()获取所有一级子标签
public list elements(string name)获取所有一级子标签中的指定标签
public element element(string name)获取一级子标签中的指定标签,若该标签有多个则获取第一个
<?xml version="1.0" encoding="gb2312"?>
<phoneinfo>
    <brand name="华为">
        <type name="u8650"/>
        <type name="hw123"/>
        <type name="hw321"/>
    </brand>
    <brand name="苹果">
        <type name="iphone4"/>
    </brand>
</phoneinfo>
package com.hsh.exercise5;

import org.dom4j.document;
import org.dom4j.element;
import org.dom4j.io.saxreader;

import java.util.list;

public class main {
    public static void main(string[] args) throws exception {
//创建一个dom4j提供的解析器对象
        saxreader saxreader = new saxreader();
        //将xml文件读取到我们的内存当中,获取到这个document 对象之后就可以读取里面的数据了
        document document = saxreader.read("./src/com/hsh/exercise5/收藏信息.xml");

        system.out.println("---获取根元素---");
        //1、获取根元素对象里面的所有信息,下面根据这个根元素对象去获取想要的数据
        element rootelement = document.getrootelement();
        system.out.println(rootelement.getname());// phoneinfo

        system.out.println("---获取所有一级子标签---");
        //2、获取根元素里面的一级子元素
        list<element> elements = rootelement.elements();
        for (element element : elements){
            // 获取标签名
            system.out.println(element.getname());
            // 获取属性值
            system.out.println(element.attributevalue("name"));
            // 获取标签内容 这是空,因为没有设置内容。
            system.out.println(element.gettext());
        }
        // brand
        // 华为
        // brand
        // 苹果
        system.out.println("---获取所有一级子标签中的指定标签---");
        //获取节点名称为books下所有子节点
        list<element> elist = rootelement.elements("brand");
        for (element element : elist){
            system.out.println(element.getname());
        }
        // brand
        // brand
        system.out.println("---获取一级子标签中的指定标签---");
        // 如果重复,则获取第一个
        element element = rootelement.element("brand");
        system.out.println(element.getname());// brand

    }
}

修改值和删除值

方法

说明

public node detach()

删除dom元素(标签)

public void setattributevalue(string name, string value)

修改属性值

原文件

<?xml version="1.0" encoding="gb2312"?>
<phoneinfo> 
  <brand name="华为"> 
    <type name="u8650"/>  
    <type name="hw123"/>  
    <type name="hw321"/> 
  </brand>  
  <brand name="苹果"> 
    <type name="iphone4"/> 
  </brand> 
</phoneinfo>

修改

package com.hsh.exercise5;

import org.dom4j.document;
import org.dom4j.element;
import org.dom4j.io.outputformat;
import org.dom4j.io.saxreader;
import org.dom4j.io.xmlwriter;

import java.io.filewriter;
import java.util.list;

public class delupdxml {
    public static void main(string[] args) throws exception {
        //创建一个dom4j提供的解析器对象
        saxreader saxreader = new saxreader();
        //将xml文件读取到我们的内存当中,获取到这个document 对象之后就可以读取里面的数据了
        document document = saxreader.read("./src/com/hsh/exercise5/收藏信息.xml");
        // 获取根元素对象
        element rootelement = document.getrootelement();
        system.out.println(rootelement.getname());
        // 获取所有一级子标签
        list<element> elements = rootelement.elements();
        for (int i = 0; i < elements.size(); i++){
            if(elements.get(i).attributevalue("name").equals("苹果")){
                // 删除
                elements.get(i).detach();
            }else {
                // 修改
                elements.get(i).setattributevalue("name", "华为手机");
            }
        }

        // 设置xml文件的格式
        outputformat outputformat = outputformat.createprettyprint();
        outputformat.setencoding("gb2312");   // 设置编码格式

        // 写入xml文件的位置 以及指定的格式
        xmlwriter xmlwriter=new xmlwriter(new filewriter("./src/com/hsh/exercise5/exercise.xml"),outputformat);
        // 开始写入xml文件   写入document对象
        xmlwriter.write(document);
        xmlwriter.close();
    }
}

结果

<?xml version="1.0" encoding="gb2312"?>

<phoneinfo> 
  <brand name="华为手机"> 
    <type name="u8650"/>  
    <type name="hw123"/>  
    <type name="hw321"/> 
  </brand> 
</phoneinfo>

添加值并保存文件

添加相关方法

方法说明
public static element createelement(string name)创建元素(标签)
element addattribute(string var1, string var2);设置元素的属性
public void add(element element)添加元素()中是传入的子元素

保存文件相关方法

方法说明
public static outputformat createprettyprint()创建xml格式
public xmlwriter(writer writer, outputformat format)参数分别是java的输出流和创建xml格式
public void write(document doc)写入document对象
public void close()关闭流
package com.hsh.exercise5;

import org.dom4j.document;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.outputformat;
import org.dom4j.io.xmlwriter;

import java.io.filewriter;

public class writexml {
    public static void main(string[] args) throws exception {
        // 创建根元素对象
        element rootelement = documenthelper.createelement("phoneinfo");
        // 创建子元素
        element brand = documenthelper.createelement("brand");
        brand.addattribute("name","华为");
        element type  = documenthelper.createelement("type");
        // 设置子元素的属性
        type.addattribute("name","p10");
        brand.add(type);
        rootelement.add(brand);
        
        // 创建document对象
        document document = documenthelper.createdocument(rootelement);

        // 设置xml文件的格式
        outputformat outputformat = outputformat.createprettyprint();
        outputformat.setencoding("gb2312");   // 设置编码格式

        // 写入xml文件的位置 以及指定的格式
        xmlwriter xmlwriter=new xmlwriter(new filewriter("./src/com/hsh/exercise5/exercise.xml"),outputformat);
        // 开始写入xml文件   写入document对象
        xmlwriter.write(document);
        xmlwriter.close();
    }
}

// 输出结果

<?xml version="1.0" encoding="gb2312"?>

<phoneinfo>
  <brand name="华为">
    <type name="p10"/>
  </brand>
</phoneinfo>

案例:使用dom4j解析xml文件

  1. 显示手机收藏信息
  2. 保存手机收藏信息
  3. 为手机收藏信息添加新的节点
  4. 修改/删除手机收藏信息节点
package com.hsh.exercise5;

public class test {
    public static void main(string[] args) throws exception {
        xmlservise xmlservise = new xmlservise("./src/com/hsh/exercise5/收藏信息.xml");

        xmlservise.addelemnet("小米","小米15");
        xmlservise.addelemnet("小米","小米14");
        xmlservise.addelemnet("三星","酸14");
        xmlservise.addelemnet("三星","三星14");
        xmlservise.addelemnet("三星","小米14");
        xmlservise.deltype("三星","小米14");
        xmlservise.delbrand("三星");
        xmlservise.updatetype("小米","小米14","小米13");
        xmlservise.updatebrand("小米","三星");
        xmlservise.updatebrand("三星","小米");
        xmlservise.save();
        xmlservise.print();
    }
}
package com.hsh.exercise5;

import org.dom4j.document;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.outputformat;
import org.dom4j.io.saxreader;
import org.dom4j.io.xmlwriter;

import java.io.filewriter;
import java.util.list;

public class xmlservise {
    public document document;
    public string url;
    saxreader saxreader = new saxreader();
    public xmlservise(string url) throws exception {
        this.url = url;
        this.document =saxreader.read(url);
    }

    public void print(){
        // 获取根节点
        element rootelement = document.getrootelement();
        // 获取根节点的所有子标签
        list<element> elements = rootelement.elements();
        for (int i = 0; i < elements.size(); i++){
            system.out.print("手机品牌:");
            //  获取属性值
            system.out.print(elements.get(i).attributevalue("name")+",");

            system.out.print("手机型号:");
            for (int j = 0; j < elements.get(i).elements().size(); j++){
                //  获取属性
                system.out.print(elements.get(i).elements().get(j).attributevalue("name")+"  ");
            }
            system.out.println();
        }
    }


    public void save() throws exception {
        // 设置xml文件的格式
        outputformat outputformat = outputformat.createprettyprint();
        outputformat.setencoding("utf-8");
        xmlwriter  xmlwriter=new xmlwriter(new filewriter(url),outputformat);
        xmlwriter.write(document);
        xmlwriter.close();
    }

    public void addelemnet(string brand, string type) throws exception{
        // 获取根节点
        element rootelement = document.getrootelement();
        boolean isbrandexist = false;
        boolean istypeexist = false;
        // 遍历查找是否有brand的name属性的名字相同的
        list<element> elements = rootelement.elements();
        for (int i = 0; i < elements.size(); i++){
            if(elements.get(i).attributevalue("name").equals(brand)){
                isbrandexist = true;
                list<element> elements1 = elements.get(i).elements();
                for (int j = 0; j < elements1.size(); j++){
                    if(elements1.get(j).attributevalue("name").equals(type)){
                        istypeexist = true;
                    }
                }
            }
        }
        if(isbrandexist){
            if(istypeexist){
                // 不添加
            }else {
                // 遍历找到该品牌并添加
                for (int i = 0; i < elements.size(); i++){
                    if(elements.get(i).attributevalue("name").equals(brand)){
                        element element = documenthelper.createelement("type");
                        element.addattribute("name",type);
                        elements.get(i).add(element);
                    }
                }
            }
        }else {
            element element = documenthelper.createelement("brand");
            element.addattribute("name",brand);
            element element1 = documenthelper.createelement("type");
            element1.addattribute("name",type);
            element.add(element1);
            rootelement.add(element);
        }


    }

    public void deltype(string brand, string type) {
        // 获取根节点
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            if(rootelement.elements().get(i).attributevalue("name").equals(brand)){
                for (int j = 0; j < rootelement.elements().get(i).elements().size(); j++){
                    if(rootelement.elements().get(i).elements().get(j).attributevalue("name").equals(type)){
                        rootelement.elements().get(i).elements().remove(j);
                    }
                }
            }
        }
    }

    public void delbrand(string brand) {
        // 获取根节点
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            if(rootelement.elements().get(i).attributevalue("name").equals(brand)){
                rootelement.elements().remove(i);
            }
        }
    }

    public void updatetype(string brand, string name, string newname) {
        // 获取根节点
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            if(rootelement.elements().get(i).attributevalue("name").equals(brand)){
                for (int j = 0; j < rootelement.elements().get(i).elements().size(); j++){
                    if(rootelement.elements().get(i).elements().get(j).attributevalue("name").equals(name)){
                        rootelement.elements().get(i).elements().get(j).addattribute("name",newname);
                    }
                }
            }
        }
    }

    public void updatebrand(string brand, string newbrand) {
        // 获取根节点
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            if(rootelement.elements().get(i).attributevalue("name").equals(brand)){
                rootelement.elements().get(i).addattribute("name",newbrand);
            }
        }
    }
}

结果

<?xml version="1.0" encoding="utf-8"?>
<phoneinfo> 
  <brand name="华为"> 
    <type name="u8650"/>  
    <type name="hw123"/>  
    <type name="hw321"/> 
  </brand>  
  <brand name="苹果"> 
    <type name="iphone4"/> 
  </brand>  
  <brand name="小米">
    <type name="小米15"/>
    <type name="小米13"/>
  </brand>
</phoneinfo>

综合案例

<?xml version="1.0" encoding="gbk"?>
<citys>
	<city id='010'>
		<cityname>北京</cityname>
		<cityarea>华北</cityarea>
		<population>2114.8万人</population>
	</city>
	<city id='021'>
		<cityname>上海</cityname>
		<cityarea>华东</cityarea>
		<population>2,500万人</population>
	</city>
	<city id='020'>
		<cityname>广州</cityname>
		<cityarea>华南</cityarea>
		<population>1292.68万人</population>
	</city>
	<city id='028'>
		<cityname>成都</cityname>
		<cityarea>华西</cityarea>
		<population>1417万人</population>
	</city>
</citys>

(1)使用dom4j将信息存入xml中

(2)读取信息,并打印控制台

(3)添加一个city节点与子节点

(4)使用socket tcp协议编写服务端与客户端,客户端输入城市id,服务器响应相应城市信息

(5)使用socket tcp协议编写服务端与客户端,客户端要求用户输入city对象,服务端接收并使用dom4j保存至xml文件

解析

这道题我的思路是

将客户端和服务端抽象成类,都有接收和发送功能。

然后把xml文件的添加,保存,查询都给保存起来。

citys.xml

<?xml version="1.0" encoding="utf-8"?>
<citys> 
  <city id="010"> 
    <cityname>北京</cityname>  
    <cityarea>华北</cityarea>  
    <population>2114.8万人</population> 
  </city>  
  <city id="021"> 
    <cityname>上海</cityname>  
    <cityarea>华东</cityarea>  
    <population>2,500万人</population> 
  </city>  
  <city id="020"> 
    <cityname>广州</cityname>  
    <cityarea>华南</cityarea>  
    <population>1292.68万人</population> 
  </city>  
  <city id="028"> 
    <cityname>成都</cityname>  
    <cityarea>华西</cityarea>  
    <population>1417万人</population> 
  </city>
</citys>

server.java

package com.hsh.homework1;

import java.io.inputstream;
import java.io.outputstream;
import java.net.serversocket;
import java.net.socket;

public class server {
    public int port;
    serversocket s;
    socket socket;
    outputstream os;
    inputstream is;

    public server(int port) {
        this.port = port;
    }

    public void start() throws exception {
        system.out.println("服务器启动成功");
        s = new serversocket(port);
        // 每使用一次 accept 说明一个客户端连接
        // 再次使用就和上一次的客户端连接断开
        socket = s.accept(); // 只 accept 一次
        is = socket.getinputstream();
        os = socket.getoutputstream();
        system.out.println("客户端已连接");
    }

    public void stop() throws exception {
        s.close();
    }

    /**
     * 发送消息 比如返回该城市的信息
     * @param msg
     * @throws exception
     */
    public void responsemsg(string msg) throws exception {
        system.out.println("服务器开始发送");
        os.write((msg+"end").getbytes());
        system.out.println("服务器发送成功");
    }

    /**
     * 接收指令
     * @return
     * @throws exception
     */
    public string receivemsg() throws exception {
        system.out.println("服务器开始接收");
        byte[] b = new byte[1024];
        int len;
        string str = "";
        boolean receivedend = false;
        while (!receivedend && (len = is.read(b)) != -1) {
            str += new string(b, 0, len);
            if (str.contains("end")) {
                str = str.replace("end", ""); // 去掉结束符
                receivedend = true;
            }
        }
        return str;
    }

}

servertest.java

package com.hsh.homework1;

public class servertest {
    public static void main(string[] args) throws exception {
        server server = new server(9999);
        server.start();
        xmlservise xmlservise = new xmlservise("src/com/hsh/homework1/citys.xml");

        while (true) {
            string msg = server.receivemsg();
            system.out.println("收到客户端指令: " + msg);
            switch (msg){
                case "1":
                    // 接收要查询的省份id
                    string provinceid = server.receivemsg();
                    system.out.println("查询省份id: " + provinceid);

                    string cityinfo = xmlservise.getcityinfo(provinceid);
                    server.responsemsg(cityinfo);
                    system.out.println();
                    break;
                case "2":
                    string addcityinfo =server.receivemsg();
                    system.out.println("添加城市信息: " + addcityinfo);
                    string[] arr = utils.split(addcityinfo);
                    xmlservise.addcity(arr[0], arr[1], arr[2], arr[3]);
                    xmlservise.save();
                    break;
                default:
                    server.responsemsg("无效指令");
                    break;
            }
        }
    }
}

client.java

package com.hsh.homework1;

import java.io.outputstream;
import java.lang.reflect.array;
import java.net.socket;
import java.util.arraylist;
import java.util.list;

public class client {
    string url;
    int port;
    socket socket;
    outputstream os;

    public client(string url, int port) {
        this.url = url;
        this.port = port;
    }

    public void start() throws exception {
        socket = new socket(url, port);
        system.out.println("客户端启动成功");
    }
    /**
     * 接收消息
     * @return
     * @throws exception
     */
    public string receivemsg() throws exception {
        system.out.println("客户端开始接收");
        socket.getinputstream();
        byte[] b = new byte[1024];
        int len;
        string str = "";
        // 循环读取,直到读取到结束符,不然可能会卡在这不往下走。
        boolean receivedend = false;
        while (!receivedend && (len = socket.getinputstream().read(b)) != -1) {
            str += new string(b, 0, len);
            if (str.contains("end")) {
                str = str.replace("end", ""); // 去掉结束符
                receivedend = true;
            }
        }
        system.out.println("客户端接收成功");

        return str;
    }

    /**
     * 关闭
     *
     * @throws exception
     */
    public void stop() throws exception {
        os.close();
        socket.close();
    }

    /**
     * 发送消息
     *
     * @param instructions
     * @throws exception
     */
    public void sendinstructions(string instructions) throws exception {
        system.out.println("客户端开始发送");
        os = socket.getoutputstream();
        os.write((instructions + "end").getbytes());
        system.out.println("客户端发送成功");
    }
}

clienttest.java

package com.hsh.homework1;
import java.util.arraylist;
import java.util.list;
import java.util.scanner;

public class clienttest {
    public static void main(string[] args) throws exception {
        client client = new client("127.0.0.1", 9999);
        client.start();
        scanner sc = new scanner(system.in);

        while (true){
            system.out.println("请选择操作");
            system.out.println("1.输入城市id查看城市信息");
            system.out.println("2.输入城市id,省份,省份归属地,人口数");
            system.out.println("3.退出");
            switch (sc.next()){
                case "1":
                    client.sendinstructions("1");
                    system.out.println("请输入城市id");
//                    client.sendid(sc.next());
                    client.sendinstructions(sc.next());
                    system.out.println(client.receivemsg());
                    break;
                case "2":
                    client.sendinstructions("2");
                    system.out.println("请输入城市id");
                    string id =sc.next();
                    system.out.println("请输入省份");
                    string province =sc.next();
                    system.out.println("请输入省份归属地");
                    string area =sc.next();
                    system.out.println("请输入人口数");
                    string population =sc.next();
                    list<string> list = new arraylist<>();
                    list.add(id);
                    list.add(province);
                    list.add(area);
                    list.add(population);
                    client.sendinstructions(list.tostring());
//                    client.sendcityinfo(id,province,area,population);
                    break;
                case "3":
                    system.out.println("退出");
                    client.stop();
                    return;
                default:
                    system.out.println("请输入正确的选项");
                    break;
            }
        }

    }
}

xmlservise.java

​
package com.hsh.homework1;

import org.dom4j.document;
import org.dom4j.documenthelper;
import org.dom4j.element;
import org.dom4j.io.outputformat;
import org.dom4j.io.saxreader;
import org.dom4j.io.xmlwriter;

import java.io.filewriter;

public class xmlservise {
    public document document;
    public string url;
    saxreader saxreader = new saxreader();
    public xmlservise(string url) throws exception {
        this.url = url;
        this.document =saxreader.read(url);
    }
    public string printxml() {
        // 直接输出xml内容
        return document.asxml();
    }
    public void print() {
        // 直接输出xml内容
        // system.out.println(document.asxml());
        // system.out.println();
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            element element = rootelement.elements().get(i);
            system.out.println(element.attributevalue("id"));
            for (int j = 0; j < element.elements().size(); j++){
                element element1 = element.elements().get(j);
                system.out.println("    "+element1.gettext());
            }
        }
    }


    public void addcity(string number, string cityname, string cityarea, string population) {
        element rootelement = document.getrootelement();
        // 创建city元素
        element city = documenthelper.createelement("city");
        city.addattribute("id",number);
        // 创建cityname元素
        element citynameelement = documenthelper.createelement("cityname");
        citynameelement.settext(cityname);
        // 创建cityarea元素
        element cityareaelement = documenthelper.createelement("cityarea");
        cityareaelement.settext(cityarea);
        // 创建population元素
        element populationelement = documenthelper.createelement("population");
        populationelement.settext(population);
        city.add(citynameelement);
        city.add(cityareaelement);
        city.add(populationelement);
        rootelement.add(city);

    }

    /**
     * 获取城市信息
     * @param provinceid
     * @return
     */
    public string getcityinfo(string provinceid) {
        element rootelement = document.getrootelement();
        for (int i = 0; i < rootelement.elements().size(); i++){
            element element = rootelement.elements().get(i);
            if(element.attributevalue("id").equals(provinceid)){
                stringbuilder stringbuilder = new stringbuilder();
                for (int j = 0; j < element.elements().size(); j++){
                    element element1 = element.elements().get(j);
                    stringbuilder.append(element1.gettext());
                    stringbuilder.append(" ");
                }
                return stringbuilder.tostring();
            }
        }
        return "没有此城市";
    }

    public void save() throws exception{
        outputformat outputformat = outputformat.createprettyprint();
        outputformat.setencoding("utf-8");
        xmlwriter  xmlwriter=new xmlwriter(new filewriter(url),outputformat);
        xmlwriter.write(document);
        xmlwriter.close();
    }
}

​

utils.java

package com.hsh.homework1;

public class utils {
    public static string[] split(string str) {
        string[] arr = str.substring(1, str.length() - 1).split(",");
        for (int i = 0; i < arr.length; i++) {
            arr[i] = arr[i].trim();
            system.out.println(arr[i]);
        }
        return arr;
    }
}

运行结果

客户端启动成功
请选择操作
1.输入城市id查看城市信息
2.输入城市id,省份,省份归属地,人口数
3.退出
1
客户端开始发送
客户端发送成功
请输入城市id
010
客户端开始发送
客户端发送成功
客户端开始接收
客户端接收成功
北京 华北 2114.8万人 

请选择操作
1.输入城市id查看城市信息
2.输入城市id,省份,省份归属地,人口数
3.退出
2
客户端开始发送
客户端发送成功
请输入城市id
035
请输入省份
河南
请输入省份归属地
华中
请输入人口数
1234万人
客户端开始发送
客户端发送成功

请选择操作
1.输入城市id查看城市信息
2.输入城市id,省份,省份归属地,人口数
3.退出
1
客户端开始发送
客户端发送成功
请输入城市id
035
客户端开始发送
客户端发送成功
客户端开始接收
客户端接收成功
河南 华中 1234万人 

请选择操作
1.输入城市id查看城市信息
2.输入城市id,省份,省份归属地,人口数
3.退出

服务器启动成功
客户端已连接
服务器开始接收
收到客户端指令: 1
服务器开始接收
查询省份id: 010
服务器开始发送
服务器发送成功

服务器开始接收
收到客户端指令: 2
服务器开始接收
添加城市信息: [035, 河南, 华中, 1234万人]
035
河南
华中
1234万人
服务器开始接收
收到客户端指令: 1
服务器开始接收
查询省份id: 035
服务器开始发送
服务器发送成功

服务器开始接收
 

<?xml version="1.0" encoding="utf-8"?>

<citys> 
  <city id="010"> 
    <cityname>北京</cityname>  
    <cityarea>华北</cityarea>  
    <population>2114.8万人</population> 
  </city>  
  <city id="021"> 
    <cityname>上海</cityname>  
    <cityarea>华东</cityarea>  
    <population>2,500万人</population> 
  </city>  
  <city id="020"> 
    <cityname>广州</cityname>  
    <cityarea>华南</cityarea>  
    <population>1292.68万人</population> 
  </city>  
  <city id="028"> 
    <cityname>成都</cityname>  
    <cityarea>华西</cityarea>  
    <population>1417万人</population> 
  </city>  
  <city id="035">
    <cityname>河南</cityname>
    <cityarea>华中</cityarea>
    <population>1234万人</population>
  </city>
</citys>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com