XML基础介绍【一】

XML基础介绍【一】

1、XML简介(Extensible Markup Language)[可扩展标记语言]
  XML全称为Extensible Markup Language, 意思是可扩展的标记语言,它是 SGML(标准通用标记语言)的一个子集。
标记语言:HTML
  可扩展标记语言
   - HTML里面标签是固定的,每个标签都有特定的含义
   - 标签可以自己定义,可以写中文标签<person></person>,<人></人>

XML用途
 - html是用于显示数据,xml也可以显示数据(并非主要功能)
 - xml主要功能:为了存储数据

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版本不能向下兼容)

2、XML的应用
a. 程序的配置文件(这也是最后大家使用XML最常见的目的);
b. 数据交换:不同语言之间用来交换数据;
c. 小型数据库:用来当数据库存储数据。
- 不同的系统之间传输数据
  QQ之间数据的传输 图解【xml应用1】

XML基础介绍【一】
 - 用来表示生活中有关系的数据
    图解【xml应用2】
XML基础介绍【一】
 - 经常用在配置文件
    比如数据库连接[用户 密码 数据库名称],修改数据库的信息,不需要修改源代码,只修改配置文件即可

3、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中文乱码问题
  - 图解
  - 保存文件时编码和设置打开的时候的编码一致 => 乱码问题解决
XML基础介绍【一】
(2)定义元素(标签)   (3)定义属性   (4)注释   (5)特殊字符   (6)CDATA区   (7)PI指令

4、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>
5、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属性的名称规范和元素的名称规格一致
6、XML的注释
   <!-- xml注释 --> (不能嵌套注释,不能放在第一行,第一行必须放xml文档的声明)
7、XML中的特殊字符
   需要进行转义【图解】
XML基础介绍【一】
8、CDATA区
   可以解决多个字符都需要转义的操作,放在CDATA区内就不需要转义
   格式:
  <![CDATA[ 内容 ]]>
  code:<![CDATA[ if>&& and < $%*{} ]]>
   把特殊字符当做文本内容,而不是标签

e-code
XML基础介绍【一】

e-image
XML基础介绍【一】

9、PI指令(处理指令)
   可在xml中设置样式(只能对英文标签起作用,对于中文的标签名称不起作用)
  <?xml-stylesheet type="text/css" href="css的路径"?>
e-code
XML基础介绍【一】
css

XML基础介绍【一】

e-image
XML基础介绍【一】

10、xml的约束简介(DTD)
 为什么要约束?
  - 比如定义一个person的xml文件,这个文件只保存人的信息。但在文件中定义了其他标签<猫>,也符合xml的语法规范。但是猫不属于人类信息,这是就需要约束xml。
e-image
XML基础介绍【一】
  xml约束技术:DTD约束、schema约束

11、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

XML基础介绍【一】

12、dtd三种引入方式
  (1)外部引入dtd:<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">【区分小大写且有空格】
e-image
XML基础介绍【一】

  (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">

13、使用DTD定义元素
   语法: <!ELEMENT 元素名 约束>

    简单元素:没有子元素的元素
    <!ELEMENT name (#PCDATA)>
     (#PCDATA): 约束name是字符串类型
     EMPTY : 元素为空(没有内容)
      - <sex></sex>
    ANY:任意
   复杂元素:
    <!ELEMENT person (name,age,sex,school)>
     - 子元素只能出现一次
    <!ELEMENT 元素名称 (子元素)>

  表示子元素出现的次数
   + : 表示一次或者多次
   ? :表示零次或者一次
   * :表示零次或者多次

  子元素直接使用逗号进行隔开 ,
   表示元素出现的顺序

  子元素直接使用|隔开
   表示元素只能出现其中的任意一个

e-image
XML基础介绍【一】

14、使用DTD定义属性
语法: <!ATTLIST 元素名称
        属性名称 属性类型 属性的约束
   >
属性类型
 - CDATA: 字符串

 - 枚举 : 表示只能在一定的范围内出现值,但是只能每次出现其中的一个

 - ID:值只能是字母或者下划线开头

属性的约束
 - #REQUIRED:属性必须存在

 - #IMPLIED:属性可有可无

 - #FIXED: 表示一个固定值 
  - 属性的值必须是设置的这个固定值
 - 直接值
   不写属性,使用直接值
   写了属性,使用设置那个值
e-code

 <?xml version="1.0" encoding="UTF-8"?>
<!-- 内部dtd -->
<!DOCTYPE person [
<!ELEMENT person (id,name+,age?,sex*,school,birthday)>
<!ELEMENT id (#PCDATA)>
<!-- 固定值 -->
<!ATTLIST id
ID1 CDATA #FIXED "xh"
> <!ELEMENT name (#PCDATA)>
<!-- 字符串 -->
<!ATTLIST name
ID2 CDATA #REQUIRED
>
<!ELEMENT age (#PCDATA)>
<!-- 可有可无 -->
<!ATTLIST age
ID3 CDATA #IMPLIED
> <!ELEMENT sex (#PCDATA)>
<!-- 枚举 -->
<!ATTLIST sex
ID4 (men|women) #REQUIRED
> <!ELEMENT school (#PCDATA)>
<!-- 直接值 -->
<!ATTLIST school
ID5 CDATA "ahzsu"
> <!ELEMENT birthday (#PCDATA)>
<!-- ID -->
<!ATTLIST birthday
ID6 ID #REQUIRED
> ]>
<person>
<id ID1="xh">2015112401</id>
<name ID2="user">zhangsan1</name>
<age>18</age>
<sex ID4="men">男</sex>
<school ID5="anhui">ahszu.edu.cn</school>
<birthday ID6="birth">2018</birthday>
</person>

e-image
XML基础介绍【一】

15、实体的定义
语法: <!ENTITY 实体名称 "实体的值">
   <!ENTITY TEST "404boom">
      使用实体 &实体名称; 比如 &TEST;

注意: 定义实体需要写在内部dtd里面,如果写在外部的dtd里面,有某些浏览器下,内容得不到
e-image
XML基础介绍【一】

16、xml的解析的简介(写到java代码)
xml是标记型文档
js使用dom解析标记型文档?
 - 根据html的层级结构,在内存中分配一个树形结构,把html的标签,属性和文本都封装成对象
 - document对象、element对象、属性对象、文本对象、Node节点对象
xml的解析方式(技术):dom 和 sax
 画解分析使用dom解析xml过程
XML基础介绍【一】
dom解析和sax解析区别:
 dom方式解析 :根据xml的层级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
  缺点:如果文件过大,造成内存溢出
  优点:很方便实现增删改操作

sax方式解析:采用事件驱动,边读边解析
  - 从上到下,一行一行的解析,解析到某一个对象,返回对象名称
  缺点:不能实现增删改操作
 优点:如果文件过大,不会造成内存溢出,方便实现查询操作

解析xml,首先需要解析器
   不同的公司和组织提供了 针对dom和sax方式的解析器,通过api方式提供
  sun公司提供了针对dom和sax解析器 jaxp
  dom4j组织,针对dom和sax解析器 dom4j(重点,也是实际开发中使用最多,功能最强)
  jdom组织,针对dom和sax解析器 jdom

17、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)
    -- 创建文本

  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 的实例。
二、sax
  SAXParser:解析器类
  SAXParserFactory:解析器工厂

18、使用jaxp实现查询操作
查询xml中第一个name元素的值
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、得到所有name元素
5、返回集合,遍历集合,得到每一个name元素
   - 遍历 getLength() item()
   - 得到元素里面的值 使用getTextContent方法

查询xml中第一个name元素的值
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、得到所有name元素
5、使用返回集合,里面方法 item,下标获取具体的元素
    NodeList.item(下标): 集合下标从0开始
6、得到具体的值,使用 getTextContent方法

查询xml中第一个name元素的值
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、得到所有name元素
5、使用返回集合,里面方法 item,下标获取具体的元素
  NodeList.item(下标): 集合下标从0开始
6、得到具体的值,使用 getTextContent方法

19、使用jaxp添加节点
在第一个p1下面(末尾)添加 <sex>nv</sex>
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、得到第一个p1
  - 得到所有p1,使用item方法下标得到

5、创建sex标签 createElement
6、创建文本 createTextNode
7、把文本添加到sex下面 appendChild

8、把sex添加到第一个p1下面 appendChild
9、回写xml

20、使用jaxp修改节点
修改第一个p1下面的sex内容是nan
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、得到sex item方法
5、修改sex里面的值
   setTextContent方法
6、回写xml

21、使用jaxp删除节点
删除<sex>nan</sex>节点
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
4、获取sex元素
5、获取sex的父节点 使用getParentNode方法
6、删除使用父节点删除 removeChild方法
7、回写xml

22、使用jaxp遍历节点
把xml中的所有元素名称打印出来
步骤:
1、创建解析器工厂
2、根据解析器工厂创建解析器
3、解析xml,返回document
* ====使用递归实现=====
4、得到根节点
5、得到根节点子节点
6、得到根节点子节点的子节点

e-code(18-22)

 package boom.jaxp;

 import java.io.IOException;

 import javax.xml.crypto.dsig.Transform;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.TransformerFactoryConfigurationError;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException; public class TestJaxp { /**
* 实现jaxp操作xml
* @param args
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// selectAll();
// selectSingle();
// addSex();
// modifySex();
// delSex();
listElement(); } // 1、查询person.xml中第一个name元素值
public static void selectSingle() throws Exception{
Document document = tempmodel(); // 得到所有的name元素
NodeList list = document.getElementsByTagName("name");
// 使用返回的集合里面的item方法,下标获取具体元素
Node name2 = list.item(0);
// 得到具体的值,使用getTextContent()
String s1 = name2.getTextContent();
System.out.println("s1="+s1); } // 1.1、查询所有的name元素的
public static void selectAll() throws Exception {
Document document = tempmodel(); // 得到name元素
NodeList list = document.getElementsByTagName("name");
// 遍历
for (int i = 0;i<list.getLength();i++) {
Node name1 = list.item(i); // 得到每一个元素的值
// 得到标签里面元素的值
String s = name1.getTextContent();
System.out.println("s="+s);
}
} // 2、在第一个p下面(末尾)添加 <sex>nv</sex>
public static void addSex() throws Exception{
Document document = tempmodel(); // 得到所有的p标签
NodeList list = document.getElementsByTagName("p");
// 得到第一个p标签
Node p = list.item(0);
// 创建标签
Element sex = document.createElement("sex");
// 创建文本
Text text = document.createTextNode("男");
// 把文本添加到sex1下面
sex.appendChild(text);
// 把sex1添加到p1下面
p.appendChild(sex);
// 回写xml文件
rexml(document);
} // 3、修改第一个p下面的sex为nv
public static void modifySex() throws Exception{
Document document = tempmodel(); // 得到sex
Node sex = document.getElementsByTagName("sex").item(0);
// 修改sex内的内容
sex.setTextContent("nv");
// 回写xml文件
rexml(document);
} // 4、使用jaxp删除节点(删除<sex>nan</sex>节点)
public static void delSex() throws Exception{
Document document = tempmodel();
// 得到sex元素
Node sex = document.getElementsByTagName("sex").item(0);
// 得到sex父节点
Node p = sex.getParentNode();
// 删除
p.removeChild(sex); // 回写xml文件
rexml(document); } // 5、遍历节点,把所有的名称的打印出来
public static void listElement() throws Exception{
Document document = tempmodel();
// 编写一个方法用于遍历操作
list(document); } /**
* 递归遍历的方法
* @param node
*/
public static void list(Node node) {
//判断是元素类型时候才打印
if(node.getNodeType() == Node.ELEMENT_NODE) {
System.out.println(node.getNodeName());
}
// 得到一层子节点
NodeList list = node.getChildNodes();
for(int i=0;i<list.getLength();i++){
// 得到每一个节点
Node node1 = list.item(i);
//继续得到node1的子节点
//node1.getChildNodes();
list(node1); } }
/**
* 被封装的tempmodel()、Retempmodel();
* @return
* @throws Exception
*/
// 头文件的tempmodel();
public static Document tempmodel() throws Exception {
// 创建解析器厂
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
// 根据解析器工厂创建解析器
DocumentBuilder builder = builderFactory.newDocumentBuilder();
// 解析xml,返回document
Document document= builder.parse("src/person.xml");
return document;
}
// Retempmodel 的xml文件();
public static void rexml(Document document) throws Exception {
// 回写xml文件
TransformerFactory tanTransformerFactory = TransformerFactory.newInstance();
Transformer transformer = tanTransformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/person.xml"));
} }

xml文件截图:
XML基础介绍【一】

上一篇:NameValueCollection类读取配置信息


下一篇:【01】emmet系列之基础介绍