XML基礎介紹【一】css
一、XML簡介(Extensible Markup Language)[可擴展標記語言]
XML全稱爲Extensible Markup Language, 意思是可擴展的標記語言,它是 SGML(標準通用標記語言)的一個子集。
標記語言:HTML
可擴展標記語言
- HTML裏面標籤是固定的,每一個標籤都有特定的含義
- 標籤能夠本身定義,能夠寫中文標籤<person></person>,<人></人>html
XML用途
- html是用於顯示數據,xml也能夠顯示數據(並不是主要功能)
- xml主要功能:爲了存儲數據java
W3C在1998年2月發佈1.0版本;
W3C在2004年2月發佈1.1版本,但由於1.1版本不能向下兼容1.0版本,因此1.1沒有人用。同時,在2004年2月W3C又發佈了1.0版本的第三版。咱們要學習的仍是1.0版本。
xml版本:1.0 1.1
- 目前使用的都是1.0版本(1.1版本不能向下兼容)node
二、XML的應用
a. 程序的配置文件(這也是最後你們使用XML最多見的目的);
b. 數據交換:不一樣語言之間用來交換數據;
c. 小型數據庫:用來當數據庫存儲數據。
- 不一樣的系統之間傳輸數據
QQ之間數據的傳輸 圖解【xml應用1】數據庫
- 用來表示生活中有關係的數據
圖解【xml應用2】
- 常常用在配置文件
好比數據庫鏈接[用戶 密碼 數據庫名稱],修改數據庫的信息,不須要修改源代碼,只修改配置文件便可apache
三、XML語法
(1)xml的文檔聲明
建立一個文件 後綴名:.xml
一個xml文件第一步必需要有一個文檔聲明用來表示xml文件的內容
文檔聲明必須第一行 <?xml version="1.0" encoding="utf-8"?>
屬性:
- version:xml的版本 1.0 1.1
- encoding:xml的編碼 [GBK UTF-8 ISO8859-1(不包含中文)]
- standalone:是否須要依賴其餘文件 yes/no
xml中文亂碼問題
- 圖解
- 保存文件時編碼和設置打開的時候的編碼一致 => 亂碼問題解決
(2)定義元素(標籤) (3)定義屬性 (4)註釋 (5)特殊字符 (6)CDATA區 (7)PI指令api
四、XML元素的定義
標籤必須成對出現<person><person/>
標籤沒有內容可在標籤內結束:空元素<student/>
標籤必須合理的嵌套
- 合理嵌套<aa><bb></bb></aa>
- 不合理嵌套<aa><bb></aa></bb>
一個xml中只能有一個根標籤,其餘標籤都是這個標籤下面的標籤
在xml中空格和換行都當成內容來解析
兩段代碼的不同
- <aa>student</aa>
- <aa>
student
</aa>
xml標籤可使中文
xml標籤中的命名規則
(1)xml代碼區分小大寫
<a> <A>:不同的含義
(2)xml的標籤不能以數字和下劃線開頭
<2a> <_aa>
(3)xml標籤不能以xml、XML、Xml等開頭
<xmla> <XmlB> <XMLC>
(4)xml的標籤不能包含空格和冒號
<a b> <a:c>
五、XML中屬性的定義
html是標記型文檔,能夠有屬性
xml是標記型文檔,也能夠有屬性
- <person id="name">student</person>
屬性的定義要求
(1)一個標籤上可有多個屬性
- <person id1="name" id2="bbb">student</person>
(2)屬性名稱不能相同
- <person id1="name" id1="bbb">student</person>
(3)屬性名稱和屬性值之間使用 = ,屬性值使用引號(單引號 or 雙引號)
(4)xml屬性的名稱規範和元素的名稱規格一致
六、XML的註釋
<!-- xml註釋 --> (不能嵌套註釋,不能放在第一行,第一行必須放xml文檔的聲明)
七、XML中的特殊字符
須要進行轉義【圖解】
八、CDATA區
能夠解決多個字符都須要轉義的操做,放在CDATA區內就不須要轉義
格式:
<![CDATA[ 內容 ]]>
code:<![CDATA[ if>&& and < $%*{} ]]>
把特殊字符當作文本內容,而不是標籤
瀏覽器
e-code網絡
e-imageapp
九、PI指令(處理指令)
可在xml中設置樣式(只能對英文標籤起做用,對於中文的標籤名稱不起做用)
<?xml-stylesheet type="text/css" href="css的路徑"?>
e-code
css
e-image
十、xml的約束簡介(DTD)
爲何要約束?
- 好比定義一個person的xml文件,這個文件只保存人的信息。但在文件中定義了其餘標籤<貓>,也符合xml的語法規範。可是貓不屬於人類信息,這是就須要約束xml。
e-image
xml約束技術:DTD約束、schema約束
十一、DTD快速入門
建立一個文件 後綴名: .dtd
步驟:
(1)看xml中有多少個元素,有幾個就在dtd中定義一個<!ELEMENT>
(2)判斷元素是簡單元素仍是複雜元素
- 複雜元素:有子元素的元素
<!ELEMENT 元素名稱 (子元素1,子元素2,....)>
- 簡單元素:沒有子元素
<!ELEMENT 元素名稱 (#PCDATA)>
(3)在xml文件中引入外部dtd文件
- <!DOCTYPE 根元素名稱 SYSTEM "dtd文件路徑">
打開xml文件使用瀏覽器打開,瀏覽器只負責校驗xml的語法,不負責檢驗約束。這時可以使用工具進行約束(MyEclipse)
MyEclipse校驗xmldtd約束【圖解】
e-image
十二、dtd三種引入方式
(1)外部引入dtd:<!DOCTYPE 根元素名稱 SYSTEM "dtd文件路徑">【區分小大寫且有空格】
e-image
(2)內部dtd
<!DOCTYPE 根元素名稱 [
<!ELEMENT 元素名稱 (子元素1,子元素2,....)>
<!ELEMENT 元素名稱 (#PCDATA)>
<!ELEMENT 元素名稱 (#PCDATA)>
]>
(3)使用外部的dtd(網絡上的dtd文件)
- <!DOCTYPE 根元素 PUBLIC "DTD名稱" "DTD文檔的URL">
- 框架struts2 使用配置文件,使用外部dtd
- <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">
1三、使用DTD定義元素
語法: <!ELEMENT 元素名 約束>
簡單元素:沒有子元素的元素
<!ELEMENT name (#PCDATA)>
(#PCDATA): 約束name是字符串類型
EMPTY : 元素爲空(沒有內容)
- <sex></sex>
ANY:任意
複雜元素:
<!ELEMENT person (name,age,sex,school)>
- 子元素只能出現一次
<!ELEMENT 元素名稱 (子元素)>
表示子元素出現的次數
+ : 表示一次或者屢次
? :表示零次或者一次
* :表示零次或者屢次
子元素直接使用逗號進行隔開 ,
表示元素出現的順序
子元素直接使用|隔開
表示元素只能出現其中的任意一個
e-image
1四、使用DTD定義屬性
語法: <!ATTLIST 元素名稱
屬性名稱 屬性類型 屬性的約束
>
屬性類型
- CDATA: 字符串
- 枚舉 : 表示只能在必定的範圍內出現值,可是隻能每次出現其中的一個
- ID:值只能是字母或者下劃線開頭
屬性的約束
- #REQUIRED:屬性必須存在
- #IMPLIED:屬性無關緊要
- #FIXED: 表示一個固定值
- 屬性的值必須是設置的這個固定值
- 直接值
不寫屬性,使用直接值
寫了屬性,使用設置那個值
e-code
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- 內部dtd --> 3 <!DOCTYPE person [ 4 <!ELEMENT person (id,name+,age?,sex*,school,birthday)> 5 <!ELEMENT id (#PCDATA)> 6 <!-- 固定值 --> 7 <!ATTLIST id 8 ID1 CDATA #FIXED "xh" 9 > 10 11 <!ELEMENT name (#PCDATA)> 12 <!-- 字符串 --> 13 <!ATTLIST name 14 ID2 CDATA #REQUIRED 15 > 16 <!ELEMENT age (#PCDATA)> 17 <!-- 無關緊要 --> 18 <!ATTLIST age 19 ID3 CDATA #IMPLIED 20 > 21 22 <!ELEMENT sex (#PCDATA)> 23 <!-- 枚舉 --> 24 <!ATTLIST sex 25 ID4 (men|women) #REQUIRED 26 > 27 28 <!ELEMENT school (#PCDATA)> 29 <!-- 直接值 --> 30 <!ATTLIST school 31 ID5 CDATA "ahzsu" 32 > 33 34 <!ELEMENT birthday (#PCDATA)> 35 <!-- ID --> 36 <!ATTLIST birthday 37 ID6 ID #REQUIRED 38 > 39 40 ]> 41 <person> 42 <id ID1="xh">2015112401</id> 43 <name ID2="user">zhangsan1</name> 44 <age>18</age> 45 <sex ID4="men">男</sex> 46 <school ID5="anhui">ahszu.edu.cn</school> 47 <birthday ID6="birth">2018</birthday> 48 </person>
e-image
1五、實體的定義
語法: <!ENTITY 實體名稱 "實體的值">
<!ENTITY TEST "404boom">
使用實體 &實體名稱; 好比 &TEST;
注意: 定義實體須要寫在內部dtd裏面,若是寫在外部的dtd裏面,有某些瀏覽器下,內容得不到
e-image
1六、xml的解析的簡介(寫到java代碼)
xml是標記型文檔
js使用dom解析標記型文檔?
- 根據html的層級結構,在內存中分配一個樹形結構,把html的標籤,屬性和文本都封裝成對象
- document對象、element對象、屬性對象、文本對象、Node節點對象
xml的解析方式(技術):dom 和 sax
畫解分析使用dom解析xml過程
dom解析和sax解析區別:
dom方式解析 :根據xml的層級結構在內存中分配一個樹形結構,把xml的標籤,屬性和文本都封裝成對象
缺點:若是文件過大,形成內存溢出
優勢:很方便實現增刪改操做
sax方式解析:採用事件驅動,邊讀邊解析
- 從上到下,一行一行的解析,解析到某一個對象,返回對象名稱
缺點:不能實現增刪改操做
優勢:若是文件過大,不會形成內存溢出,方便實現查詢操做
解析xml,首先須要解析器
不一樣的公司和組織提供了 針對dom和sax方式的解析器,經過api方式提供
sun公司提供了針對dom和sax解析器 jaxp
dom4j組織,針對dom和sax解析器 dom4j(重點,也是實際開發中使用最多,功能最強)
jdom組織,針對dom和sax解析器 jdom
1七、jaxp的api的查看
jaxp是Javase的一部分
jaxp解析器在JDK的javax.xml.parsers包裏
四個類:分別針對dom和sax解析使用的類
1、dom
DocumentBuilder:解析器類
這個類是一個抽象類,不能new,此類的實例能夠從 DocumentBuilderFactory.newDocumentBuilder() 方法獲取。
一個方法,能夠解析xml parse("xml路徑") 返回是 Document 整個文檔。
返回的document是一個接口,父節點是Node,若是在document裏面找不到想要的方法,到Node裏面去找
- 在document裏面方法
getElementsByTagName(String tagname)
-- 這個方法能夠獲得標籤
-- 返回集合 NodeList
createElement(String tagName)
-- 建立標籤
createTextNode(String data)
-- 建立文本
appendChild(Node newChild)
-- 把文本添加到標籤下面
removeChild(Node oldChild)
-- 刪除節點
getParentNode()
-- 獲取父節點
NodeList list
- getLength() 獲得集合的長度
- item(int index)下標取到具體的值
for(int i=0;i<list.getLength();i++) {
list.item(i);
}
getTextContent()
- 獲得標籤裏面的內容
DocumentBuilderFactory:解析工廠
- 這個類也是一個抽象類,不能new
newInstance() 獲取 DocumentBuilderFactory 的實例。
2、sax
SAXParser:解析器類
SAXParserFactory:解析器工廠
1八、使用jaxp實現查詢操做
查詢xml中第一個name元素的值
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲得全部name元素
五、返回集合,遍歷集合,獲得每個name元素
- 遍歷 getLength() item()
- 獲得元素裏面的值 使用getTextContent方法
查詢xml中第一個name元素的值
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲得全部name元素
五、使用返回集合,裏面方法 item,下標獲取具體的元素
NodeList.item(下標): 集合下標從0開始
六、獲得具體的值,使用 getTextContent方法
查詢xml中第一個name元素的值
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲得全部name元素
五、使用返回集合,裏面方法 item,下標獲取具體的元素
NodeList.item(下標): 集合下標從0開始
六、獲得具體的值,使用 getTextContent方法
1九、使用jaxp添加節點
在第一個p1下面(末尾)添加 <sex>nv</sex>
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲得第一個p1
- 獲得全部p1,使用item方法下標獲得
五、建立sex標籤 createElement
六、建立文本 createTextNode
七、把文本添加到sex下面 appendChild
八、把sex添加到第一個p1下面 appendChild
九、回寫xml
20、使用jaxp修改節點
修改第一個p1下面的sex內容是nan
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲得sex item方法
五、修改sex裏面的值
setTextContent方法
六、回寫xml
2一、使用jaxp刪除節點
刪除<sex>nan</sex>節點
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
四、獲取sex元素
五、獲取sex的父節點 使用getParentNode方法
六、刪除使用父節點刪除 removeChild方法
七、回寫xml
2二、使用jaxp遍歷節點
把xml中的全部元素名稱打印出來
步驟:
一、建立解析器工廠
二、根據解析器工廠建立解析器
三、解析xml,返回document
* ====使用遞歸實現=====
四、獲得根節點
五、獲得根節點子節點
六、獲得根節點子節點的子節點
e-code(18-22)
1 package boom.jaxp; 2 3 import java.io.IOException; 4 5 import javax.xml.crypto.dsig.Transform; 6 import javax.xml.parsers.DocumentBuilder; 7 import javax.xml.parsers.DocumentBuilderFactory; 8 import javax.xml.parsers.ParserConfigurationException; 9 import javax.xml.transform.Transformer; 10 import javax.xml.transform.TransformerConfigurationException; 11 import javax.xml.transform.TransformerException; 12 import javax.xml.transform.TransformerFactory; 13 import javax.xml.transform.TransformerFactoryConfigurationError; 14 import javax.xml.transform.dom.DOMSource; 15 import javax.xml.transform.stream.StreamResult; 16 17 import org.w3c.dom.Document; 18 import org.w3c.dom.Element; 19 import org.w3c.dom.Node; 20 import org.w3c.dom.NodeList; 21 import org.w3c.dom.Text; 22 import org.xml.sax.SAXException; 23 24 public class TestJaxp { 25 26 /** 27 * 實現jaxp操做xml 28 * @param args 29 * @throws Exception 30 */ 31 public static void main(String[] args) throws Exception { 32 // selectAll(); 33 // selectSingle(); 34 // addSex(); 35 // modifySex(); 36 // delSex(); 37 listElement(); 38 39 } 40 41 // 一、查詢person.xml中第一個name元素值 42 public static void selectSingle() throws Exception{ 43 Document document = tempmodel(); 44 45 // 獲得全部的name元素 46 NodeList list = document.getElementsByTagName("name"); 47 // 使用返回的集合裏面的item方法,下標獲取具體元素 48 Node name2 = list.item(0); 49 // 獲得具體的值,使用getTextContent() 50 String s1 = name2.getTextContent(); 51 System.out.println("s1="+s1); 52 53 } 54 55 // 1.一、查詢全部的name元素的 56 public static void selectAll() throws Exception { 57 Document document = tempmodel(); 58 59 // 獲得name元素 60 NodeList list = document.getElementsByTagName("name"); 61 // 遍歷 62 for (int i = 0;i<list.getLength();i++) { 63 Node name1 = list.item(i); // 獲得每個元素的值 64 // 獲得標籤裏面元素的值 65 String s = name1.getTextContent(); 66 System.out.println("s="+s); 67 } 68 } 69 70 // 二、在第一個p下面(末尾)添加 <sex>nv</sex> 71 public static void addSex() throws Exception{ 72 Document document = tempmodel(); 73 74 // 獲得全部的p標籤 75 NodeList list = document.getElementsByTagName("p"); 76 // 獲得第一個p標籤 77 Node p = list.item(0); 78 // 建立標籤 79 Element sex = document.createElement("sex"); 80 // 建立文本 81 Text text = document.createTextNode("男"); 82 // 把文本添加到sex1下面 83 sex.appendChild(text); 84 // 把sex1添加到p1下面 85 p.appendChild(sex); 86 // 回寫xml文件 87 rexml(document); 88 } 89 90 // 三、修改第一個p下面的sex爲nv 91 public static void modifySex() throws Exception{ 92 Document document = tempmodel(); 93 94 // 獲得sex 95 Node sex = document.getElementsByTagName("sex").item(0); 96 // 修改sex內的內容 97 sex.setTextContent("nv"); 98 // 回寫xml文件 99 rexml(document); 100 } 101 102 // 四、使用jaxp刪除節點(刪除<sex>nan</sex>節點) 103 public static void delSex() throws Exception{ 104 Document document = tempmodel(); 105 // 獲得sex元素 106 Node sex = document.getElementsByTagName("sex").item(0); 107 // 獲得sex父節點 108 Node p = sex.getParentNode(); 109 // 刪除 110 p.removeChild(sex); 111 112 // 回寫xml文件 113 rexml(document); 114 115 } 116 117 // 五、遍歷節點,把全部的名稱的打印出來 118 public static void listElement() throws Exception{ 119 Document document = tempmodel(); 120 // 編寫一個方法用於遍歷操做 121 list(document); 122 123 } 124 125 126 /** 127 * 遞歸遍歷的方法 128 * @param node 129 */ 130 public static void list(Node node) { 131 //判斷是元素類型時候纔打印 132 if(node.getNodeType() == Node.ELEMENT_NODE) { 133 System.out.println(node.getNodeName()); 134 } 135 // 獲得一層子節點 136 NodeList list = node.getChildNodes(); 137 for(int i=0;i<list.getLength();i++){ 138 // 獲得每個節點 139 Node node1 = list.item(i); 140 //繼續獲得node1的子節點 141 //node1.getChildNodes(); 142 list(node1); 143 144 } 145 146 } 147 /** 148 * 被封裝的tempmodel()、Retempmodel(); 149 * @return 150 * @throws Exception 151 */ 152 // 頭文件的tempmodel(); 153 public static Document tempmodel() throws Exception { 154 // 建立解析器廠 155 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); 156 // 根據解析器工廠建立解析器 157 DocumentBuilder builder = builderFactory.newDocumentBuilder(); 158 // 解析xml,返回document 159 Document document= builder.parse("src/person.xml"); 160 return document; 161 } 162 // Retempmodel 的xml文件(); 163 public static void rexml(Document document) throws Exception { 164 // 回寫xml文件 165 TransformerFactory tanTransformerFactory = TransformerFactory.newInstance(); 166 Transformer transformer = tanTransformerFactory.newTransformer(); 167 transformer.transform(new DOMSource(document), new StreamResult("src/person.xml")); 168 } 169 170 171 }
xml文件截圖: