1.xml的简介-extensible markup language:可扩展标记型语言(了解)
1.1标记型语言:html是标记型语言,使用标签操作
-不同于html之处:可扩展:html里面的标签是固定的,每个标签都有特定的含义
标签可以自己定义,可以写中文标签
1.2 xml用途:
-html用于显示数据,xml也可以显示数据(不是主要功能)
-xml主要功能是为了存储数据
1.3 xml两个版本1.0 1.1版本,1.1版本不能向下兼容
-是w3c组织发布的技术
2.xml的应用
2.1 不同的系统之间传输数据,有利于程序的维护
2.2 用来表示生活中有关系的数据
2.3 作为配置文件
-比如连接数据库,需要知道数据库的用户名和密码,数据库名称
-如果修改数据库的信息,不需要修改源代码,只需要修改配置文件
3. xml的语法
3.1 xml的文档声明
-创建一个文件,后缀名是.xml
-若写xml,第一步必须要有一个文档声明(写了文档声明后,表示写xml文件的内容)
--<?xml version="1.0" encoding="gbk"?>
--文档声明必须在第一行第一列
-属性
--version:xml的版本1.0(使用) 1.1
--encoding:xml编码 gbk utf-8 iso8859-1(不包含中文)
--standalone:是否需要依赖其他文件 yes/no
-解决中文乱码的问题
<?version="1.0" encoding="utf-8"?> <person> <name>张三</name> <age>20</age> </person>
--代码保存到本地硬盘,使用gbk编码保存
--将“张三”转换到gbk码表里面对应的数字
--打开xml文件时,使用设置的编码 utf-8
--在utf-8码表中找到数字对应的文字,出现乱码
--解决方案:设置保存的编码和打开的编码一致
3.2 定义元素(标签)
-标签定义有开始必须要有结束:<person></person>
-标签没有内容,可以在标签内结束:<aa/>
-标签可以嵌套,必须要合理嵌套
--合理嵌套<aa><bb></bb></aa>
--不合理嵌套<aa><bb></aa></bb>
-一个xml中,只能有一个根标签,其他标签都是这个标签下面的标签
-在xml中把空格和换行都当成内容来解析,下方两段代码含义不同
<aa>11111</aa> <aa> 11111 </aa>
-xml中标签的命名规则
--xml代码区分大小写
--标签名称不能以数字或下划线开头
--标签名称不能以xml、XML、Xml开头
--标签名称中不能包含空格和冒号
3.3 定义属性
-HTML是标记型文档,可以有属性;xml也是标记型文档,可以有属性
-<person id="aaa"></person>
-属性定义的要求
--一个标签上可以有多个属性
<person id1="aaa" id2="bbb"></person>
--属性名称不能相同
--属性名称和属性值使用=,属性值使用引号包起来
--xml属性的名称规范和元素的名称规范一致
3.4 注释
-写法:<!--注释的写法-->
-注意点:注释不能嵌套,注释也不能放在第一行
3.5 特殊字符
-对特殊字符进行转义
-- < <
-- > >
-- & &
-- " "
--' '
3.6 CDATA区(了解)
-可以解决多个字符都需要转义的操作,将需要转义的内容放到CDATA区里面,即不需转义
-写法 <![CDATA[内容]]>
<![CDATA[<b>if(a>b && b>c){}</b>]]>
3.7 PI指令(了解)
-可以在xml中设置样式
<?xml-stylesheet type="text/css" href="1.css"?>
-设置样式,只能对英文标签名称起作用,对中文标签不起作用。
3.8 xml的约束
-需要约束的原因:比如定义一个person的xml文件,只想在该文件中保存人的信息,比如name、age等,但是如若在xml文件中写了一个标签<猫>,可以正常显示,但是猫不是人的基本信息,需要技术来规定xml中只能出现的元素,这个时候需要约束
-xml的约束技术:dtd约束和schema约束(看懂)
3.9 dtd的快速入门
-创建一个文件 :后缀名 .dtd
-步骤: (1)看xml中有多少个元素,有几个元素,在dtd文件中写几个<!ELEMENT>
(2)判断元素是简单元素还是复杂元素
--复杂元素为有子元素的元素<!ELEMENT 元素名称 (子元素)>
--简单元素为没有子元素的元素<!ELEMENT 元素名称 (#PCDATA)>
(3)在xml文件中引入dtd文件
<!DATYPE 根元素名称 SYSTEM "dtd文件的路径">
-浏览器只负责校验xml的语法,不负责校验约束
-利用myeclipse开发工具校验xml的约束
3.10 dtd三种引入方式
-引入外部的dtd文件
<!DATYPE 根元素名称 SYSTEM "dtd文件的路径">
-使用内部的dtd文件
<!DOCTYPE 根元素名称[ <!ELEMENT person (name,age)> <!ELEMENT name (#PCDATA)> <!ELEMENT age (#PCDATA)> ]>
-使用外部的dtd文件(网络上的dtd文件)
<!DOCTYPE 根元素 PUBLIC “ DTD名称” “DTD文档的URL”>
3.11 使用dtd定义元素
-语法:<!ELEMENT 元素名 约束>
-简单元素:没有子元素的元素
--(#PCDATA):约束元素是字符串类型
--EMPTY:元素为空(没有内容)
--ANY:任意
-复杂元素:
--语法格式:<!ELEMENT 元素名称(子元素序列)>
--子元素只能出现一次
--表示子元素出现的次数
+ :表示一次或者多次
?:表示零次或一次
* :表示零次或多次
--子元素直接使用逗号进行隔开,表示子元素出现的顺序
--子元素直接使用 | 进行隔开,表示元素只能出现其中任意的一个
3.12 使用dtd定义属性
-语法: <!ATTLIST 元素名称
属性名称 属性类型 属性的约束
>
-属性类型
--CDATA:字符串
<!ATTLIST birthday ID1 CDATA #REQUIRED >
--枚举:(aa|bb|cc)表示只能在一定的范围内出现值,但是只能每次出现其中的一个(交通信号灯效果)
<!ATTLIST age ID2 (AA|BB|CC) #REQUIRED >
--ID:值只能是字母或者下划线开头
<!ATTLIST name ID3 ID #REQUIRED >
-属性的约束
--#REQUIRED:表示该属性必须出现
--#IMPLIED:表示该属性可有可无
--#FIXED:表示一个固定值 #FIXED "AAA"
表示属性值必须是AAA
<!ATTLIST sex ID4 CDATA #FIXED "ABC" >
--直接值:不写属性,使用该直接值;写属性,使用设置的那个值
<!ATTLIST school ID5 CDATA "www" >
3.13 实体的定义
-语法: <!ENTITY 实体名称 “实体的值”>
<!ENTITY TEST "HAHAHEHE">
-使用实体: &实体名称;
<name ID3="ss11">&TEST;</name>
-注意:定义的实体需要写在内部dtd里面,若写在外部,会导致在某些浏览器中不能得到该内容
<?xml version="1.0" encoding="UTF-8"?> <!-- <!DOCTYPE person SYSTEM "1.dtd"> --> <!DOCTYPE person[ <!ELEMENT person (name+,age?,sex*,school,birthday)> <!--<!ELEMENT person (name+|age?|sex*|school)>--> <!ELEMENT name (#PCDATA)> <!ATTLIST name ID3 ID #REQUIRED > <!ELEMENT age (#PCDATA)> <!ATTLIST age ID2 (AA|BB|CC) #REQUIRED > <!ELEMENT sex EMPTY> <!ATTLIST sex ID4 CDATA #FIXED "ABC" > <!ELEMENT school (#PCDATA)> <!ATTLIST school ID5 CDATA "www" > <!ELEMENT birthday (#PCDATA)> <!ATTLIST birthday ID1 CDATA #IMPLIED > <!ENTITY TEST "HAHAHEHE"> ]> <person> <name ID3="ss11">&TEST;</name> <age ID2="AA">20</age> <sex ID4="ABC"></sex> <school ID5="a">11111</school> <birthday ID1="aaa">2015</birthday> </person>
3.14 xml的解析的简介(写到java代码)(重要的很)
-xml是标记型文档
-js使用dom解析标记型文档:根据HTML的层级结构,在内存中分配一个树形结构,把HTML的标签,属性和文本都封装成对象
document对象、element对象、属性对象、文本对象、node节点对象
-xml的解析方式:dom和sax
--dom方式解析:根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
缺点:若文件过大,造成内存溢出
优点:很方便实现增删改操作
--sax方式解析:采用事件驱动,边读边解析;从上到下,一行一行的解析,解析到某一个对象,返回对象名称
缺点:不能实现增删改操作
优点:如文件过大,不会造成内存溢出,方便实现查询操作
-想要解析xml,首先需要解析器
--不同的公司和组织提供了 针对dom和sax方式的解析器,通过api方式提供
Sum公司针对两种解析器 jaxp
dom4j组织针对两种解析器 dom4j(实际开发)
jdom组织针对两种解析器 jdom
3.15 JAXP的api查看
-jaxp是javase的一部分
-jaxp解析器是jdk的javax.xml.parsers包里面
--四个类:分别是针对dom和sax解析使用的类
--dom:
DocumentBuilder:解析器类
---这个类是抽象类,不能new,此类实例可以通过DocumentBuilderFactory.newDocumentBuilder()方法获取
---一个方法,可以解析xml: parse("xml路径") 返回是 Document 整个文档
---返回的document是一个接口,父节点是Node,如果在document里面找到到想要的方法,在node里面找
---在document里面方法
* getElementsByTagName(String tagname) 方法得到标签,返回集合NodeList
*createElement(String tagName)方法创建标签
*createTextNode(String data)方法创建文本
---在node中方法
*appendChild(Node newChild)把文本添加到标签下面
*removeChild(Node oldChild)删除节点
*getParentNode()获取父节点
---Nodelist接口中方法
*getLength()得到集合的长度
*item(int index) 下标取到具体的值
*getTextContent()得到元素中的内容
for(int i=0;i<list.getLength();i++){ list.item(i); }
DocumentBuilderFactory:解析器工厂
---这个类也是一个抽象类,不能new,newInstance()获取 DocumentBuilderFactory的实例
--sax:
SAXParser:解析器类
SAXParserFactory:解析器工厂
3.16 使用jaxp实现查询操作
-查询xml中所有的name元素的值
-步骤
*1.创建解析器工厂
*2.根据解析器工厂创建解析器
*3.解析xml返回document
*4.得到所有的name元素
*5.返回集合,遍历结合,得到每一个name元素
//创建解析器工厂 alt/:代码提示 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //解析xml,返回document Document document=builder.parse("src/person.xml"); //得到name元素 NodeList list=document.getElementsByTagName("name"); for(int i=0;i<list.getLength();i++){ Node name1=list.item(i);//得到每一个name元素 //得到标签里面的内容 String s=name1.getTextContent(); System.out.println(s); }
-查询xml中第一个元素的值
-步骤
*1、创建解析器工厂
*2.根据解析器工厂创建解析器
*3.解析xml返回document
*4.得到所有name元素
*5.返回集合,里面方法item,下标获取具体的元素(集合下标从0开始)
*6.得到具体的值getTextContent()
//得到解析器工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //返回document Document document=builder.parse("src/person.xml"); //得到所有name元素 NodeList list=document.getElementsByTagName("name"); //返回第一个下标值 String s=list.item(0).getTextContent(); System.out.println(s);
3.17 使用jaxp添加节点
-在第一个p1末尾添加<sex>nv</sex>
public static void addSex()throws Exception{ /* *1、创建解析器工厂 *2.根据解析器工厂创建解析器 *3.解析xml返回document *4.得到第一个p1 * -得到所有p1,使用item方法下标得到 *5.创建sex标签 createElement *6.创建文本createTextNode *7.把文本添加到sex下面appendChild *8.把sex添加到第一个p1下面 *9.回写xml */ //创建解析器工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //返回document Document document=builder.parse("src/person.xml"); //得到第一个p1 Node p1=document.getElementsByTagName("p1").item(0); //创建sex标签 Element sex=document.createElement("sex"); //创建文本 Text nv=document.createTextNode("nv"); //将文本添加到sex下面 sex.appendChild(nv); //将sex添加到第一个p1下面s p1.appendChild(sex); //回写xml TransformerFactory transformerFactory=TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/person.xml")); }
3.18 使用jaxp修改节点
-修改第一个p1下面的性别为男
public static void modifySex() throws Exception{ /* *1、创建解析器工厂 *2.根据解析器工厂创建解析器 *3.解析xml返回document *4.得到sex item方法 *5.修改sex里面的值 setTextContent方法 *6.回写xml */ //创建解析器工厂 DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder builder=builderFactory.newDocumentBuilder(); //解析xml返回document Document document=builder.parse("src/person.xml"); //得到sex NodeList list=document.getElementsByTagName("sex"); //修改第一个sex里面的值 list.item(0).setTextContent("nan"); //回写xml TransformerFactory transformerFactory=TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/person.xml")); }
3.19 使用jaxp删除节点
-删除sex节点
//删除sex节点 public static void delSex()throws Exception{ /* * 1、创建解析器工厂 *2.根据解析器工厂创建解析器 *3.解析xml返回document *4.获取sex元素 *5.获取sex的父节点 *6.使用父节点删除removeChild方法 *7.回写xml */ //创建解析器工厂 DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); //解析xml Document document=documentBuilder.parse("src/person.xml"); //获取sex元素 Node sex=document.getElementsByTagName("sex").item(0); //获取sex的父节点 Node sexf=sex.getParentNode(); //删除sex节点 sexf.removeChild(sex); //回写xml TransformerFactory transformerFactory=TransformerFactory.newInstance(); Transformer transformer=transformerFactory.newTransformer(); transformer.transform(new DOMSource(document), new StreamResult("src/person.xml")); }
3.20 使用jaxp遍历节点
-将xml中所有的元素名称打印出来
//遍历节点,把所有元素名称打印出来 public static void listElement() throws Exception{ /* * 1、创建解析器工厂 *2.根据解析器工厂创建解析器 *3.解析xml返回document * *===使用递归实现=== *4.得到根节点 *5.得到根节点子节点 *6.得到根节点子节点的子节点 */ //创建解析器工厂 DocumentBuilderFactory documentBuilderFactory=DocumentBuilderFactory.newInstance(); //创建解析器 DocumentBuilder documentBuilder=documentBuilderFactory.newDocumentBuilder(); //解析xml Document document=documentBuilder.parse("src/person.xml"); //编写一个方法实现遍历操作 list1(document); } private static void list1(Node node) { //判断是元素类型的时候才打印 if(node.getNodeType()==Node.ELEMENT_NODE){ System.out.println(node.getNodeName()); } // TODO Auto-generated method stub //得到一层子节点 NodeList list=node.getChildNodes(); //遍历list for(int i=0;i<list.getLength();i++){ //得到每一个子节点 Node node1=list.item(i); //继续得到node1子节点 list1(node1); } }