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文件截图: