本文主要是介绍java中XML的使用全过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
《java中XML的使用全过程》:本文主要介绍java中XML的使用全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教...
什么是XML
XML(EXtensible Markup Language),可扩展标记语言,是一种简单的基于文本的语言,旨在以村文本格式存储和传输数据,他代表可扩展标记语言。
特点
实现不同系统之间的数据交换
XML作用
XML的编写语法
基本语法
- 所有XML元素都必须有结束标签
- XML标签对大小写敏感
- XML必须正确的嵌套
- 同级标签以缩进对齐
- 元素名称可以包含字母、数字或其他的字符
- 元素名称不能以数字或者标点符号开始
- 元素名称中不能含空格
<?xml version="1.0" encoding="UTF-8"?> <books> <!--图书信息 这是注释--> <book id="bk101"> php <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中书写”<’
“&”等,可能会出现冲突,导致报错,此时可以用如下特殊字符替代。
指定字符 | 特殊字符 | 含义 |
---|---|---|
< | < | 小于 |
> | > | 大于 |
& | & | 小于 |
' | ’ | 单引号 |
" | " | 双引号 |
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 > 2 && 3 < 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)
- 基于XML文档树结构的解析
- 适用于多次访问的XML文档
- 特点:比较消耗资源
SAX(内置解析XML)
- 基于事件的解析
- 适用于大数据量的XML文档
- 特点:占用资源少,内存消耗小
DOM4J
- 非常优秀的Java XML API
- 性能优异、功能强大
- 开放源代码
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文件步骤
- 创建解析器工厂对象
- 解析器工厂对象创建解析器对象
- 解析器对象指定XML文件创建Document对象
- 以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文件
步骤
- 获得TransformerFactory对象
- 创建Transformer对象
- 创建DOMSource对象:包含XML信息
- 设置输出属性:编码格式
- 创建StreamResult对象:包含保存文件的信息
- 将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节点
添加手机收藏
- 添加新的Brand:三星
- 给Brand节点添加新的子标签Type:Note4
- 将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.appendChildChina编程(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")China编程; 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文件
- 显示手机收藏信息
- 保存手机收藏信息
- 为手机收藏信息添加新的节点
- 修改/删除手机收藏信息节点
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"/&androidgt; <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>
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持China编程(www.chinasem.cn)。
这篇关于java中XML的使用全过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!