XML简介
- XML是指可扩展标记语言(eXtensible Markup Language),是一种标记语言,很类似HTML,它被设计的宗旨是传输数据,而非显示数据
- XML标签没有被预定义,需要用户自定义标签
- XML技术是W3C组织发布的
XML的应用
-
不同系统之间传输数据
-
用来表示生活中有关系的数据
-
经常用在配置文件中
XML的文档声明
-
创建文件的后缀名是
.xml
-
如果要写一个xml文件,第一步必须要有文档声明,表示写的是xml文件
<?xml version="1.0" encoding="gbk"?>
,文档声明必须写在第一行第一列,version属性表示版本,有1.0和1.1,一般使用1.0,encoding属性表示编码,另一个属性standalone,表示是否需要依赖其他文件,若需要写standalone=“yes”,不需要standalone=“no”
XML的中文乱码问题解决
设置保存时候的编码方式和打开时的编码方式一致即可
XML元素(标签)的定义
-
标签定义有开始必须要有结束,
<person></person>
-
如果标签没有内容,可以在标签内结束,如:
<person/>
-
标签可以嵌套,如:
<a><b></b></a>
-
一个xml文件中必须要有且仅有一个根标签,其它的标签都是这个标签下的标签
-
对于xml标签中出现的所有空格和换行,xml解析程序都会当做标签内容来处理
-
xml中标签的命名规则
(1)xml代码区分大小写
(2)标签名称不能以数字或_开头
(3)xml的标签不能以XML、xml、Xml等开头
(4)标签不能包含空格和冒号
(5)xml的标签可以是中文
XML中属性的定义
xml是标记型文档,可以有属性,如:<person id="aaa"></person>
属性定义的要求:
-
一个标签上可以有多个属性
-
属性值要用引号(单引号或双引号)引起来
-
属性名称的命名规范与标签名称的命名规范一样
xml的注释
<!--这是注释-->
,xml中注释不能嵌套
xml的特殊字符
需要对特殊字符进行转义才能正常显示,如要显示a<b,可以写成a<b
,>用>
转义,双引号用"
转义,单引号用'
转义
xml的CDATA区
如果有多个字符都需要转义,可以把它们整体放到CDATA区里,就不需要转义了
写法:<![CDATA[内容]]>
xml的PI指令(处理指令)
作用:用来指挥软件如何解析xml文件,可以设置样式(一般没啥用)
xml-stylesheet指令:<?xml-stylesheet type="text/css" href="#"?>
,只能对英文标签名称起作用
xml的约束简介
比如现在定义一个person的xml文件,只想要在这个文件里面保存人的相关信息,但是在xml文件中写了一个<猫>标签,虽然可以正常显示,但它不是人的信息,这时需要技术来规定xml中只能出现的元素,这就是约束。xml中的约束技术:dtd约束、schema约束
-
dtd快速入门(能看懂就行)
(1)创建dtd文件,后缀名为.dtd
(2)xml文件中有几个元素,就在dtd文件中写几个<!ELEMENT>
(3)复杂元素(有子元素)写法:<!ELEMENT 元素名称 (子元素1,子元素2)>
(4)简单元素(无子元素)写法:<!ELEMENT 元素名称 (#PCDATA)>
(5)在xml文件中引入dtd文件,<!DOCTYPE 根元素名称 SYSTEM "dtd文件的路径">
(6)用浏览器打开xml文件,浏览器只校验语法,不校验约束,需要使用工具来校验约束 -
dtd的引入方式
(1)引入外部dtd文件,<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
(2)使用内部dtd文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person [
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
<person>
<name>zhangsan</name>
<age>20</age>
</person>
(3)从公共网络上引入dtd文档,<!DOCTYPE 根元素名称 PUBLIC "dtd名称" "dtd文档的url">
-
在dtd文档中使用ELEMENT关键字来声明一个XML元素
(1)语法:<!ELEMENT 元素名 使用规则>
(2)简单元素约束例如:<!ELEMENT name (#PCDATA)>
,其中, (#PCDATA)约束name是字符串类型,若为EMPTY,则约束<name></name>
中内容为空,若为ANY,则可空也可不空
(3)复杂元素约束如:<!ELEMENT person (name,age)>
表示子元素出现的次数:若写成name+,表示name可以出现一次或多次;若写成age?,表示age可以出现0次或1次;若写成name*,表示name可以出现0次或1次或多次。在<!ELEMENT person (name,age)>
中元素之间用逗号隔开,并且有顺序,若用 | 隔开,则表示这些子元素只能出现其中的任意一个 -
使用dtd定义属性
语法:
<!ATTLIST 元素名称
属性1名称 属性类型 属性的约束
属性2名称 属性类型 属性的约束
>
属性类型:
CDATA:表示属性的取值为普通的文本字符串
枚举:只能从枚举列表中任选其一,如(鸡肉|牛肉|鱼肉)
ID:表示属性的取值不能重复,属性的值只能由字母、下划线开头,不能出现空白字符
属性约束设置说明:
#REQUIRED:表示该属性必须出现
#IMPLIED:表示该属性可有可无
#FIXED:表示属性的取值为一个固定值,语法:#FIXED "固定值"
直接值:表示属性的取值为该默认值,若不写属性,则使用直接值,若写属性,则使用设置的那个值
- 定义实体
概念:在dtd中定义,在xml中使用
语法:<!ENTITY 实体名称 "实体内容">
引用方式:&实体名称;
如在dtd中定义:<!ENTITY test "haha">
在xml中使用:<name>&test;</name>
注意:定义实体一般写在内部dtd中,如果写在外部dtd里面,在某些浏览器下,内容得不到
xml的解析的简介
-
js使用dom解析HTML文档:根据HTML的层级结构,在内存中分配一个树形结构,把HTML的标签、属性和文本都封装成对象,有document对象、属性对象、文本对象、Node节点对象等
-
xml的解析方式(技术):dom和sax
(1)使用dom方式解析xml时,如果文件过大,会造成内存溢出,但可以很方便的实现增删改操作
(2)sax解析过程:采用事件驱动,边读边解析(一行一行地解析,解析到某一个对象,把对象名称返回)。这种解析方式不会造成内存溢出,可以方便实现查询,但不能实现增删改操作 -
想要解析xml,首先需要解析器,不同的公司和组织提供了针对dom和sax方式的解析器,通过api的方式提供。如sun公司的jaxp,dom4j组织的dom4j(实际开发中使用最多),jdom组织的jdom
jaxp的api的查看
-
JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成
org.w3c.dom:提供DOM方式解析XML的标准接口
org.xml.sax:提供SAX方式解析XML的标准接口
javax.xml:提供了解析XML文档的类 -
javax.xml.parsers包中,定义了几个工厂类,我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象
(1)针对dom:DocumentBuilder(解析器类)、DocumentBuilderFactory(解析器工厂)
DocumentBuilder:这是个抽象类,不能new,此类的实例可以从DocumentBuilderFactory.newDocumentBuilder()方法获取。这里面有一个方法parse(“xml的路径”)可以解析xml,返回的是Document整个文档,Document是个接口,其父接口是Node,如果在Document里面找不到想要的方法,可以到Node中去找。在Document中有个方法getElementByTagName(String tagname),这个方法可以得到标签,返回集合NodeList,还有创建标签的方法createElement(String tagname),创建文本的方法createTextNode(String data),Node里面有appendChild(Node newChild)方法可以添加节点
DocumentBuilderFactory:这也是个抽象类,不能new,newInstance()方法获取实例
(2)针对sax:SAXParser(解析器类)、SAXParserFactory(解析器工厂)
使用jaxp查询节点
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
</p1>
<p1>
<name>lisi</name>
<age>25</age>
</p1>
</person>
需求:查询xml中所有的name元素的值
package packagetest;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class classtest {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//查询所有name元素的值
/* 1、创建解析器工厂
* 2、根据解析器工厂创建解析器
* 3、解析xml返回Document
* 4、得到所有的name元素
* 5、返回集合,遍历集合,得到每一个name元素
*
*/
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
NodeList list=document.getElementsByTagName("name"); //得到name元素
for(int i=0;i<list.getLength();i++) {
Node name1=list.item(i); //得到每一个name元素
String s=name1.getTextContent(); //得到标签里面的内容
System.out.println(s);
}
}
}
使用jaxp查询某一个节点
若要获取第一个节点值,可使用代码
Node name1=list.item(0);
String s=name1.getTextContent();
System.out.println(s);
使用jaxp添加节点
需求:在上面第一个<p1></p1>
中添加一个sex
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
NodeList list=document.getElementsByTagName("p1"); //得到所有的p1
Node p1=list.item(0);