1、xml的简介
* extensible Markup Language: 可扩展标记型语言
**标记型语言:html是标记型语言
-也是使用标签来操作
**可扩展:
-html里面的标签是固定,每个标签都有特定的含义<h1> <br/> <hr/>
-标签可以自己定义,可以写中文的标签<person></person><猫></猫>
- xml用途
** html是用来显示数据,xml也可以显示数据(不是主要功能〉
** xml主要功能,为了存储数据 - xml是w3c组织发布的技术
- xml有两个版本1.0 1.1
-使用都是1.0版本,(1.1版本不能向下兼容)
2、xml的应用
*不同的系统之间传输数据
*用来表示生活中有关系的数据
*经常用在配置文件中
**比如现在连接数据库,肯定知道的数据库用户名和密码,数据名称
**如果修改数据库的倌息,不需要修改原代码,只要修改配置文件就可以了
3、xml的语法
(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
*xml的中文乱码问题解决
**保存时候的编码和设置打开时候的编码一致,不会出现乱码问题
4、xml的元素定义
**标签定义
**标签定义又开始必须要有结束:<person></person>
**标签没有内容,可以再标签内结束:<aa/>
**标签必须合理嵌套
**一个xml中只能有一个根标签
**xml中把空格和换行都当成内容来解析,下面两个代码含义不同
***<aa>1111111</aa>
***<aa>
1111111
</aa>
**xml可以是中文,但是不能css
**xml中标签的命名规则
***xml代码区分大小写
***xml的标签不能以数字和下划线开头
***xml的标签不能以xml、XML、Xml等开头
***xml的标签不能包含空格和冒号
5、xml中属性的定义
*html是标记型文档,可以有属性
*xml也是标记型文档,可以有属性
*<person id1="aaa" id2="bbb"></person>
**属性定义的要求
(1)一个标签上可以有多个属性
(2)属性名称不能相同
(3)属性名称和属性值之间使用 = ,属性值使用引号(单双引号都可以)包起来
(4)xml属性命名规范和元素一致
6、xml中的注释
*
*注释不能嵌套,也不能放在第一行
7、xml中的特殊字符
*如果想要再xml中显示<,>,&,’,"需要用到转义字符
< <
> >
& &
" "
' '
8、CDATA区
*可以解决多个字符都需要转义的操作
*<![CDATA[ 内容 ]]>
9、PI指令(处理指令)
*可以在xml中设置样式
*写法:<?xml-stylesheet type="text/css" href="css路径"?>
*设置样式只能对英文标签名称起作用。
10、xml的约束
*为什么需要约束?规定xml中可以出现的元素
*xml的约束技术:dtd约束和schema约束
11、dtd的快速入门
*创建一个文件 后缀名 .dtd
步骤:
1.看xml中有多少个元素,有几个元素,在dtd文件中写几个<!ELEMENT>
2.判断元素是简单还是复杂元素
-复杂元素:<!ELEMENT 元素名称(子元素)>
<!ELEMENT student (name,age,sex)> --xml元素出现的顺序必须按照这个来
-简单元素:<!ELEMENT 元素名称 (#PCDATA)>
<!ELEMENT name (#PCDATA)> 顺序随意
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
3.需要在xml文件中引入dtd文件
**打开xml文件使用浏览器,浏览器只负责校验xml的语法,不负责校验约束
**校验xml约束,需要使用工具
**元素类型声明
-复杂元素:<!ELEMENT 元素名称(子元素)>
<!ELEMENT student (name,age,sex)> --xml元素出现的顺序必须按照这个来
-简单元素:<!ELEMENT 元素名称 (#PCDATA)>
<!ELEMENT name (#PCDATA)> 顺序随意
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ELEMENT student (name,age,sex,telphone|handset)> --电话号码,手机号码必须有一个
<!ELEMENT student (name,age,sex,telphone*)> --电话号码,零个或者多个
<!ELEMENT student (name,age,sex,telphone+> --电话号码,一个或者多个
<!ELEMENT student (name,age,sex,telphone?> --电话号码,零个或者一个
**实体类型声明:表示需要重复使用的数据,定义实体需要写在内部dtd里面,
如果写在外部的dtd里面,在某些浏览器下,内容得不到
一般实体:<!ENTITY bank_name "长沙银行"> --- 实体名称 实体内容
<bank><bankname>&bank_name</bankname></bank> ---实体引用
参数实体(只能在dtd中引用):
<!ENTITY % cityname "长沙市">
<!ENTITY bank_name "%cityname;商业银行">
**使用dtd定义属性
<!ATTLIST 元素名 属性名 属性类型 默认声明>
*属性类型
-CDATA:字符串 <!ATTLIST birthday ID1 CDATA #REQUIRED>
-枚举:表示只能在一定范围内出现值,并且只出现其中一个
<!ATTLIST age ID2 (AA|BB|CC) #REQUIRED>
-ID:值只能是字母或者下划线开头
<!ATTLIST name ID3 ID #REQUIRED>
*属性的约束
-#REQUIRED:属性必须存在
-#IMPLIED:属性可有可无
-#FIXED:表示一个固定值 #FIXED "AAA" 只能是AAA
-直接值:不写属性,使用直接值;写了属性,使用设置那个值。
12、dtd的三种引入方式
1.引入外部的dtd文件
2.使用内部的dtd文件
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
3.使用外部的dtd文件(网络上的dtd文件)
(后面struts2中使用配置文件会用到)
xml的解析的简介(写到java代码)<今天最重要的内容)
-
xml是标记型文档
-
js使用dom解析标记型文档?
-根据html的层级结构,在内存中分配—个树形结构,把html的标签,属性和文本都封装成对象
-document对象、element对象、属性对象、文本对象、Node节点对象 -
xml的解析方式(技术) :dom 和 sax
**画图分析使用dom和sax解析xml过程
*** dom解析和sax解析区别: T
** dom方式解析
*根据xml的®级结构在内存中分配一个树形结构,把xml的标签,属性和文本都封装成对象
*缺点:如果文件过大,造成内存溢出
*优点:很方便实现增删改操作
** sax方式解析
*采用事件驱动,边读边解析
-从上到下,一行一行的解析,解析到某一个对象,返回对象名称
*缺点:不能实现增删改操作
*优点:如果文件过大,不会造成内存溢出,方便实现査询操作*想要解析xml,苜先需要解析器 **不同的公司和组织提供了 针对dom和sax方式的解析器,通过api方式提供 *** sun公司提供了针对dom和sax解析器 jaxp *** dom4j组织对dom和sax解析器 dom4j (*** 实际开发中****) *** jdom组织,针对dom和sax解析器 jdom
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)
--创建标签
appendChild(Node new Child)
--把文本添加到标签下面
removeChild(Node oldChild)
--删除节点
getParentNode()
--得到父节点
NodeList list1
for(int i = 0;i<list1.getLength();i++){
list1.item(i);//得到元素
}
DocumentBuilderFactory:解析器工厂
***sax:
SAXParser:解析器类
SAXParserFactory:解析器工厂
schema快速入门
*schema后缀名 .xsd
根节点:<schema>
***在schema文件里*
**属性 xmlns="http://www.w3.org/2001/XMLSchema" 固定写法,表示是一个约束文件
**targetNamespace="http://www.w3school.com.cn" 显示被此 schema 定义的元素来自此-命名空间。
**elementFormDefault="qualified" 固定写法,表示在此 schema 中声明过的元素必须被命名空间限定
步骤:
1.看xml中有多少个元素就有多少个<element>
2.复杂元素
<complexType>
<sequence>
子元素
</sequence>
</complexType>
3.简单元素,写在复杂元素里面
最常用的类型是:
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time
<element name="age" type="integer"></element>
<xs:element name="color" type="xs:string" default="red"/>---默认值red
<xs:element name="color" type="xs:string" fixed="red"/>---固定值
**在被约束文件中引用约束文件
<note xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.w3school.com.cn"
xsi:schemaLocation="http://www.w3school.com.cn note.xsd">
**xmlns:xsi 固定写法 表示xml是一个被约束文件,xsi是起的别名
**xmlns 约束文档里的targetNamespace
**xsi:schemaLocation="targetNamespace 约束文档的url"
schema知识点
**简单元素:
<xs:element name="xxx" type="yyy"/> xxx 指元素的名称,yyy 指元素的数据类型,xs是前缀
属性:<xs:attribute name="xxx" type="yyy"/> xxx是属性名称,yyy是属性的数据类型
<xs:attribute name="lang" type="xs:string" default="EN"/> 默认值,fixed="EN" 固定值 use="required" 可选的
常见数据类型
xs:string
xs:decimal
xs:integer
xs:boolean
xs:date
xs:time
<xs:element name="age">
**简单元素的限定
age 的值不能低于 0 或者高于 120
<xs:simpleType>
<xs:restriction base="xs:integer">
<xs:minInclusive value="0"/>
<xs:maxInclusive value="120"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
下面的例子定义了带有一个限定的名为 "car" 的元素。可接受的值只有:Audi, Golf, BMW:(枚举约束)
<xs:element name="car">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
上面的例子也可以被写为:(在这种情况下,类型 "carType" 可被其他元素使用,因为它不是 "car" 元素的组成部分。)
<xs:element name="car" type="carType"/>
<xs:simpleType name="carType">
<xs:restriction base="xs:string">
<xs:enumeration value="Audi"/>
<xs:enumeration value="Golf"/>
<xs:enumeration value="BMW"/>
</xs:restriction>
</xs:simpleType>
定义了带有一个限定的名为 "initials" 的元素。可接受的值是大写或小写字母 a - z 其中的三个(模式约束
<xs:element name="initials">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[a-zA-Z][a-zA-Z][a-zA-Z]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
定义了带有一个限定的名为 "choice 的元素。可接受的值是字母 x, y 或 z 中的一个:
<xs:element name="choice">
<xs:simpleType>
<xs:restriction base="xs:string">
<xs:pattern value="[xyz]"/>
</xs:restriction>
</xs:simpleType>
</xs:element>
**复杂元素
有四种类型的复合元素:
空元素 <product pid="1345"/>
包含其他元素的元素
<employee>
<firstname>John</firstname>
<lastname>Smith</lastname>
</employee>
仅包含文本的元素 <food type="dessert">Ice cream</food>
包含元素和文本的元素
<description>
It happened on <date lang="norwegian">03.03.99</date> ....
</description>
写法一:
<xs:element name="employee">
<xs:complexType>
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
写法二:(这种写法多个元素可以通过type共用一个复杂类型)
<xs:element name="employee" type="personinfo"/>
<xs:complexType name="personinfo">
<xs:sequence>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
</xs:sequence>
</xs:complexType>
sax解析
*解析xml有两种技术dom和sax
-dom:根据xml层级结构在内存中分配一个树形结构
把xml中的标签,属性,文本封装成对象
*sax方式:事件驱动,边读边解析
*在javax.xml.parsers包中
**SAXParser
此类的实力可以从SAXParserFactory.newSAXParser()方法得到
-parse(File f,DefaultHandler dh)
*第一个参数,xml的路径
*第二个参数:事件处理器
使用jaxp的方式解析xml
*sax方式不能是西安增删改操作,只能做查询操作
**打印出整个文档
执行parse(url,事件处理器)方法
创建一个类,继承事件处理器的类
重写里面三个方法
class MyDefault extends DefaultHandler{}
saxParser.parse("student.xml", new MyDefault());
*获取到所有的name元素的值
定义一个成员变量 falg=false
判断开始方法是否是name元素,如果是name元素,把flag置true
如果flag是true,在characters方法里打印内容
执行到结束方法时候,把flag置false
*获得第一个name元素的值
定义一个成员变量 idx=1
在结束方法中 idx自增1
想要打印第一个name元素的值,就在characters方法里面判断,如果flag==true&&idx==1,打印
使用dom4j解析xml
导入dom4j jar包--创建一个lib文件夹--复制jar包到lib下面--右键jar包->build path-add to buildpath
得到document
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("student.xml");
doucment中的找不到的方法去父接口Node中找
getRootElement() 获取根节点,返回Element
Element也是一个接口,父接口是Node
getParent():获取父节点
addElement:添加标签
element(qname)获取标签下面的第一个子标签,返回Element
elements(qname)获取标签下面所有子标签(一层),返回List,用List<Element>接一下
elements()获得标签下面一层子标签,返回List
遍历List
for(Element element : list){}增强for循环,第二个list元素 list.get(1);
getText()得到内容,返回String
在p1下面添加sex
Element sex = p1.addElement("sex");
sex.setText("male");
回写xml
OutputFormat format = OutputFormat.createPrettyPrint();//带格式化的
//OutputFormat format = OutputFormat.createCompactPrint();//紧凑的
XMLWriter xmlWriter = new XMLWriter(new FileOutPutStream("student.xml"),format);
xmlWriter.writer(document);//写入文件,返回布尔
xmlWriter.close();关闭流
特定节点添加(使用list的add方法添加特定位置的元素)
List<Element> list = p1.elements();//获得p1下的所有元素
Element school = DocumentHelper.createElement("school");//创建元素
school.setText("中学");//设置文本
list.add(1,school);//第二个位置插入,然后回写
获得父节点:getParent();
删除节点:父节点.remove(element);
得到属性值:attributeValue("id"),返回String
使用dom4j支持xpath操作
*可以直接获取到某个元素
*第一种形式
/AAA/DDD/BBB:表示一层一层的,AAA下面的DDD下面的BBB
*第二种形式
//BBB:表示只要名称是BBB的都得到
*第三种形式
/*:所有元素
*第四种形式
** BBB[1]:表示第一个BBB元素
** BBB[last()]:表示最后一个BBB元素
*第五种形式
** //BBB[@id]:表示得到所有BBB上有id属性的元素
*第六种形式
**//BBB[@id='b1']:表示得到所有BBB上id属性为b1的元素
具体操作:
**默认情况下,dom4j不支持xpath
**想要在dom4j里面使用xpath,就要导入jar包(jaxen-1.1-beat-6.jar)
**在dom4j里面提供了两个支持xpath的方法:
*** selectNodes("xpath表达式")
-获得多个节点
*** selectSingleNode("xpath表达式")
-获得一个节点
**使用xpath实现:查询xml中所有name元素的值
**所有name元素的xpath表示://name
**步骤:
//得到document
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("student.xml");
//得到所有name元素
List<node> list = document.selectNodes("//name");
//遍历list集合
for(Node node : list){
//node是每一个name元素
//得到name元素里面的值
String s = node.getText();
syso(s);
}
**获取id为aaaa的p1下的name值
**xpath表示://p1[@id='aaaa']/name
Node name = document.selectSingleNode("//p1[@id='aaaa']/name");