java中XML的使用全過程
什么是XML
XML(EXtensible Markup Language),可擴展標記語言,是一種簡單的基于文本的語言,旨在以村文本格式存儲和傳輸數(shù)據(jù),他代表可擴展標記語言。
- 1、作為系統(tǒng)的配置文件
- 2、作為一種特殊的數(shù)據(jù)結構,在網(wǎng)絡中進行傳輸
特點
XML與操作系統(tǒng)、編程語言的開發(fā)平臺無關
實現(xiàn)不同系統(tǒng)之間的數(shù)據(jù)交換
XML作用
- 數(shù)據(jù)交互
- 配置應用程序和網(wǎng)站
- Ajax基石
XML的編寫語法
基本語法
- 所有XML元素都必須有結束標簽
- XML標簽對大小寫敏感
- XML必須正確的嵌套
- 同級標簽以縮進對齊
- 元素名稱可以包含字母、數(shù)字或其他的字符
- 元素名稱不能以數(shù)字或者標點符號開始
- 元素名稱中不能含空格
<?xml version="1.0" encoding="UTF-8"?>
<books>
<!--圖書信息 這是注釋-->
<book id="bk101">
<author>王珊</author>
<title>.NET高級編程</title>
<description>包含C#框架和網(wǎng)絡編程等</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中書寫”<’
“&”等,可能會出現(xiàn)沖突,導致報錯,此時可以用如下特殊字符替代。
| 指定字符 | 特殊字符 | 含義 |
|---|---|---|
| < | < | 小于 |
| > | > | 大于 |
| & | & | 小于 |
| ' | ’ | 單引號 |
| " | " | 雙引號 |
2、CDATA的數(shù)據(jù)區(qū)
XML中可以寫一個叫CDATA的數(shù)據(jù)區(qū):<![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文件的編寫
- 不能約束具體的數(shù)據(jù)類型
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.羅琳</作者>
<!-- 售價的類型可以是浮點型,字符串,也可以是任何數(shù)據(jù)類型 -->
<售價>49.9</售價>
</書>
<書>
<書名>西游記</書名>
<作者>吳承恩</作者>
<售價>49.9</售價>
</書>
</書架>schema文檔
特點
- 可以約束XML文件的編寫
- 可以約束具體的數(shù)據(jù)類型
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規(guī)范作為默認命名空間,所有未加前綴的標簽均屬于該規(guī)范。 -->
<!-- targetNamespace(目標命名空間): 申明約束文檔的地址(命名空間) 這里的data.xsd也是被約束的 -->
<!-- elementFormDefault(元素命名空間規(guī)則): 先不用管,這是關于局部元素的命名空間歸屬的屬性-->
<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文件中,出現(xiàn)名稱相同,但是含義不同的元素
<?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的方法
本節(jié)分三塊
DOM(內置解析XML)
- 基于XML文檔樹結構的解析
- 適用于多次訪問的XML文檔
- 特點:比較消耗資源
SAX(內置解析XML)
- 基于事件的解析
- 適用于大數(shù)據(jù)量的XML文檔
- 特點:占用資源少,內存消耗小
DOM4J
- 非常優(yōu)秀的Java XML API
- 性能優(yōu)異、功能強大
- 開放源代碼
??DOM解析XML
基于XML文檔樹結構的解析
適用于多次訪問的XML文檔
特點:比較消耗資源
DOM介紹
文檔對象模型(Document Object Model)
DOM把XML文檔映射成一個倒掛的樹

DOM解析包:org.w3c.dom
org.w3c.dom?? 是 Java 中用于處理 ??文檔對象模型(DOM)?? 的核心包,由 ??萬維網(wǎng)聯(lián)盟(W3C)?? 制定并維護。它是 W3C DOM 標準的 Java 語言綁定實現(xiàn),主要用于解析、訪問和操作 XML/HTML 文檔的結構化內容。(jdk自帶的用于解析xml文件的API)
常用接口
| 常用接口 | 常用方法 | 說明 |
|---|---|---|
| Document:表示整個 XML 文檔 | NodeList getElementsByTagName(String Tag) | 按文檔順序返回文檔中指定標記名稱的所有元素集合 |
| Element createElement(String tagName) | 創(chuàng)建指定標記名稱的元素 | |
| Node:該文檔樹中的單個節(jié)點 | NodeList getChildNodes() | 獲取該元素的所有子節(jié)點,返回節(jié)點集合 |
| Element:XML 文檔中的一個元素 | String getTagName() | 獲取元素名稱 |
DOM解析包的使用
DOM解析XML文件步驟
- 創(chuàng)建解析器工廠對象
- 解析器工廠對象創(chuàng)建解析器對象
- 解析器對象指定XML文件創(chuàng)建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 {
// 創(chuàng)建解析器工廠對象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 解析器工廠對象創(chuàng)建解析器對象
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 節(jié)點并打印 name 屬性
for (int i = 0; i < brandList.getLength(); i++) {
// 獲取 Brand 元素
Element brand = (Element) brandList.item(i);
// 獲取節(jié)點名稱
System.out.print(brand.getNodeName()+": ");
// 獲取 name 屬性
System.out.print(brand.getAttribute("name")+",");
// 獲取節(jié)點文本內容 由于是單標簽所以為空。
// 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);
// 獲取節(jié)點名稱
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對象
- 創(chuàng)建Transformer對象
- 創(chuàng)建DOMSource對象:包含XML信息
- 設置輸出屬性:編碼格式
- 創(chuàng)建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. 創(chuàng)建工廠TransformerFactory對象
TransformerFactory factory = TransformerFactory.newInstance();
//2. 創(chuàng)建Transformer對象
Transformer transformer = factory.newTransformer();
// 3. 創(chuàng)建Document對象來創(chuàng)建新的XML文件,給XML文件設置內容,并將DOM結構添加到DOMsource對象
// 3.1 創(chuàng)建Document對象
DocumentBuilderFactory documentFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = documentFactory.newDocumentBuilder();
Document document = builder.newDocument();
// 3.2 創(chuàng)建XML結構(即給XML文件設置內容)
// 創(chuàng)建根元素
Element root = document.createElement("root");
// 加入到document中
document.appendChild(root);
// 創(chuàng)建子元素
Element child = document.createElement("child");
// 設置屬性名和屬性值
child.setAttribute("name", "hsh");
// 設置元素內容
child.appendChild(document.createTextNode("Text Content"));
//加入根節(jié)點樹中
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. 創(chuàng)建StreamResult對象,指定輸出文件 StreamResult對象包含了文件信息
StreamResult result = new StreamResult("./src/com/hsh/exercise3/collection.xml");
// 6. 將DOMsource對象和StreamResult對象作為參數(shù)傳遞給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節(jié)點
添加手機收藏
- 添加新的Brand:三星
- 給Brand節(jié)點添加新的子標簽Type:Note4
- 將Brand添加到DOM樹中
練習:給手機收藏信息XML中添加新的手機信息,并將手機收藏信息保存到新文件中
添加新的Brand:三星
給Brand節(jié)點添加新的子標簽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 {
// 創(chuàng)建解析器工廠對象
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);
// 創(chuàng)建工廠進行保存
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節(jié)點
給所有的Brand標簽添加id屬性
- 獲取Brand標簽
- 調用setAttribute()方法添加屬性
刪除Brand值為“華為”的標簽
- getElementsByTagName()方法獲取Brand標簽列表
- 獲得Brand值為“華為”的標簽對象
- 通過getParentNode()方法獲得父節(jié)點對象
- 調用父節(jié)點的removeChild()方法刪除節(jié)點
<?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 {
// 創(chuàng)建解析器工廠對象
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);
}
}
// 創(chuàng)建工廠進行保存
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
基于事件的解析
適用于大數(shù)據(jù)量的XML文檔
特點:占用資源少,內存消耗小
DOM4J
優(yōu)點
- 非常優(yōu)秀的Java XML API
- 性能優(yōu)異、功能強大
開放源代碼
- Document:定義XML文檔
- Element:定義XML元素
- Text:定義XML文本節(jié)點
- Attribute:定義了XML 的屬性
DOM4J下載和導入項目
1、下載相關jar包
方法一:去DOM4j官網(wǎng)

2、將下載的jar包導入到idea項目中去


3、將jar包添加到庫中

點擊確定,打開lib出現(xiàn)如下界面就說明添加成功。

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 {
//創(chuàng)建一個dom4j提供的解析器對象
SAXReader saxReader = new SAXReader();
//將xml文件讀取到我們的內存當中,獲取到這個Document 對象之后就可以讀取里面的數(shù)據(jù)了
Document document = saxReader.read("./src/com/hsh/exercise5/收藏信息.xml");
System.out.println("---獲取根元素---");
//1、獲取根元素對象里面的所有信息,下面根據(jù)這個根元素對象去獲取想要的數(shù)據(jù)
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("---獲取所有一級子標簽中的指定標簽---");
//獲取節(jié)點名稱為books下所有子節(jié)點
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 {
//創(chuàng)建一個dom4j提供的解析器對象
SAXReader saxReader = new SAXReader();
//將xml文件讀取到我們的內存當中,獲取到這個Document 對象之后就可以讀取里面的數(shù)據(jù)了
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) | 創(chuàng)建元素(標簽) |
| Element addAttribute(String var1, String var2); | 設置元素的屬性 |
| public void add(Element element) | 添加元素()中是傳入的子元素 |
保存文件相關方法
| 方法 | 說明 |
|---|---|
| public static OutputFormat createPrettyPrint() | 創(chuàng)建xml格式 |
| public XMLWriter(Writer writer, OutputFormat format) | 參數(shù)分別是java的輸出流和創(chuàng)建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 {
// 創(chuàng)建根元素對象
Element rootElement = DocumentHelper.createElement("PhoneInfo");
// 創(chuàng)建子元素
Element Brand = DocumentHelper.createElement("Brand");
Brand.addAttribute("name","華為");
Element Type = DocumentHelper.createElement("Type");
// 設置子元素的屬性
Type.addAttribute("name","P10");
Brand.add(Type);
rootElement.add(Brand);
// 創(chuàng)建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文件
- 顯示手機收藏信息
- 保存手機收藏信息
- 為手機收藏信息添加新的節(jié)點
- 修改/刪除手機收藏信息節(jié)點
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(){
// 獲取根節(jié)點
Element rootElement = document.getRootElement();
// 獲取根節(jié)點的所有子標簽
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{
// 獲取根節(jié)點
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) {
// 獲取根節(jié)點
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) {
// 獲取根節(jié)點
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) {
// 獲取根節(jié)點
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) {
// 獲取根節(jié)點
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節(jié)點與子節(jié)點
(4)使用socket TCP協(xié)議編寫服務端與客戶端,客戶端輸入城市ID,服務器響應相應城市信息
(5)使用socket TCP協(xié)議編寫服務端與客戶端,客戶端要求用戶輸入city對象,服務端接收并使用dom4j保存至XML文件
解析
這道題我的思路是
將客戶端和服務端抽象成類,都有接收和發(fā)送功能。
然后把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();
}
/**
* 發(fā)送消息 比如返回該城市的信息
* @param msg
* @throws Exception
*/
public void responseMsg(String msg) throws Exception {
System.out.println("服務器開始發(fā)送");
os.write((msg+"END").getBytes());
System.out.println("服務器發(fā)送成功");
}
/**
* 接收指令
* @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 = "";
// 循環(huán)讀取,直到讀取到結束符,不然可能會卡在這不往下走。
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();
}
/**
* 發(fā)送消息
*
* @param instructions
* @throws Exception
*/
public void sendInstructions(String instructions) throws Exception {
System.out.println("客戶端開始發(fā)送");
os = socket.getOutputStream();
os.write((instructions + "END").getBytes());
System.out.println("客戶端發(fā)送成功");
}
}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,省份,省份歸屬地,人口數(shù)");
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("請輸入人口數(shù)");
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();
// 創(chuàng)建city元素
Element city = DocumentHelper.createElement("city");
city.addAttribute("id",number);
// 創(chuàng)建cityname元素
Element citynameElement = DocumentHelper.createElement("cityname");
citynameElement.setText(cityname);
// 創(chuàng)建cityarea元素
Element cityareaElement = DocumentHelper.createElement("cityarea");
cityareaElement.setText(cityarea);
// 創(chuàng)建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,省份,省份歸屬地,人口數(shù)
3.退出
1
客戶端開始發(fā)送
客戶端發(fā)送成功
請輸入城市ID
010
客戶端開始發(fā)送
客戶端發(fā)送成功
客戶端開始接收
客戶端接收成功
北京 華北 2114.8萬人請選擇操作
1.輸入城市ID查看城市信息
2.輸入城市id,省份,省份歸屬地,人口數(shù)
3.退出
2
客戶端開始發(fā)送
客戶端發(fā)送成功
請輸入城市ID
035
請輸入省份
河南
請輸入省份歸屬地
華中
請輸入人口數(shù)
1234萬人
客戶端開始發(fā)送
客戶端發(fā)送成功請選擇操作
1.輸入城市ID查看城市信息
2.輸入城市id,省份,省份歸屬地,人口數(shù)
3.退出
1
客戶端開始發(fā)送
客戶端發(fā)送成功
請輸入城市ID
035
客戶端開始發(fā)送
客戶端發(fā)送成功
客戶端開始接收
客戶端接收成功
河南 華中 1234萬人請選擇操作
1.輸入城市ID查看城市信息
2.輸入城市id,省份,省份歸屬地,人口數(shù)
3.退出
服務器啟動成功
客戶端已連接
服務器開始接收
收到客戶端指令: 1
服務器開始接收
查詢省份id: 010
服務器開始發(fā)送
服務器發(fā)送成功服務器開始接收
收到客戶端指令: 2
服務器開始接收
添加城市信息: [035, 河南, 華中, 1234萬人]
035
河南
華中
1234萬人
服務器開始接收
收到客戶端指令: 1
服務器開始接收
查詢省份id: 035
服務器開始發(fā)送
服務器發(fā)送成功服務器開始接收
<?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>總結
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關文章
java實現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印
這篇文章主要給大家介紹了關于java實現(xiàn)給圖片加鋪滿的網(wǎng)格式文字水印的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
Spring?Boot?集成Redisson實現(xiàn)分布式鎖詳細案例
這篇文章主要介紹了Spring?Boot?集成Redisson實現(xiàn)分布式鎖詳細案例,文章圍繞主題展開詳細的內容介紹,具有一定的參考價值,需要的朋友可以參考一下2022-08-08
springboot如何讀取application.yml文件
這篇文章主要介紹了springboot如何讀取application.yml文件的方法,幫助大家更好的理解和使用springboot框架,感興趣的朋友可以了解下2020-12-12
myeclipse開發(fā)servlet_動力節(jié)點Java學院整理
MyEclipse,是在eclipse基礎上加上自己的插件開發(fā)而成的功能強大的企業(yè)級集成開發(fā)環(huán)境,主要用于Java、Java EE以及移動應用的開發(fā)。下面這篇文章主要給大家介紹了關于myeclipse開發(fā)servlet的相關資料,需要的朋友可以參考下。2017-07-07
java驗證用戶是否已經(jīng)登錄 java實現(xiàn)自動登錄
這篇文章主要介紹了java驗證用戶是否已經(jīng)登錄,java實現(xiàn)自動登錄,感興趣的小伙伴們可以參考一下2016-04-04

