1. 标记语言
标记语言,是一种文本(Text)以及文本相关的其他信息结合起来,展现出关于文档结构和数据处理细节的电脑文字编码.当今广泛使用的标记语言是超文本标记语言(Hyper Text Markup Language,HTML)和可扩展标记语言(eXtensible Markup Language,XML). 标记语言广泛应用于网页和网络应用程序.
1) 超文本标记语言HTML(Hyper Text Markup Language)
写法格式: <a href="link.html">link</a>
关注数据的展示与用户体验
标记是固定的,不可扩展(如<a></a>表示超连接)
2) 可扩展的标记语言XML(eXtensible Markup Language)
写法格式:同html样式<a>link</a>
仅关注数据本身
标记可扩展,可自定义
3) Xml 和 Html语言由同一种父语言SGML(Standard Generalized Markup language,标准通用标记语言)发展出来.
4)解析器
专业解析器(比如:XML SPY 专用于解析XML文件)
浏览器
MyEclipse
5)W3C(World Wide Web Consortium)
W3C:开源的语言协会,万维网联盟(World Wide Web Consortium)
HTML 和 XML 都是W3C制定的语言规则
官网:www.w3.org
学习网站:www.w3school.com.cn
2.xml语法规则
2.1 xml的声明:
xml的声明必须写在文件第一行
Encoding(字符集)属性可以省略,默认的字符集是utf-8
例子:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <书> 3 <武侠小说 isbn="1001"> 4 <书名>天龙八部</书名> 5 <作者>金庸</作者> 6 <价格>50</价格> 7 <简介>一本好书</简介> 8 </武侠小说> 9 <计算机> 10 <书名>疯狂java</书名> 11 <作者>李刚</作者> 12 <价格>50</价格> 13 <简介>一本好书</简介> 14 </计算机> 15 </书>
常见错误写法:
1) "?"和xml之间不能有空格
2) 声明必须顶头写,不能有空行或空格(用FireFox浏览器打开)
3) 等号左右不要多写空格(java程序员的习惯)
浏览器不会报错,但是在xml解析时会出问题
2.2 标记
1)诸如<书名></书名>,这样格式的被称为标记
2)标记必须成对出现
3)标记包含开始标记和结束标记
<书名>天龙八部</ 书名>
注意:标记大小写敏感
2.3元素(Element)
1) 元素: 元素= 标记 + 其中内容 ,
如<书名>天龙八部</书名>
2) 根元素: 最外层的元素 (如 <书></书>)
3) 叶子元素: 最里层(没有子元素的)的元素 (如,<书名></书名>,<价格></价格>)
4) 空元素: 没有内容的元素叫空元素,比如:<a></a> ,<br></br>,可以简写为<a/> <br/>
5) 元素必须遵循的语法规则
a. 所有的标记都必须有结束
b.开始标记和结束标记必须成对出现
c.元素必须正确嵌套
<a><b>c</b></a> (正确)
<a><b>c</a></b> (错误)
d.标记的大小写敏感Hello 和 hello不是同一个标记
e.有且只能有一个根元素
2.4 实体引用(转义字符)
1) 小于号(<) : less then --> <
2) 大于号(>) : great than --> >
3) And符号(&) : &
4) 双引号 ( ") : "
5) 单引号( ') : '
注意这些转义字符都是以&开头,以 ; 结尾
例如:想给天龙八部加上书名号<<天龙八部>>
<?xml version="1.0" encoding="UTF-8"?> <书> <武侠小说 isbn="1001"> <书名><<天龙八部>></书名> <作者>金庸</作者> <价格>50</价格> <简介>一本好书</简介> </武侠小说> </书>
2.5属性(定义在开始标记中的键值对)
1)格式: 属性="属性值"
如<武侠小说 isbn="1234"></武侠小说>
isbn是武侠小说的属性,值是1234
2)要求:
属性必须有值
属性值必须用引号引起来,单引号或双引号都可以,但必须一致
2.6 CDATA 类型的数据:特殊标签
1) 格式: <![CDATA[文本内容]]>
2) 特殊标签中的实体引用都被忽略,所有内容被当成一整块文本数据对待
例如
<书> <武侠小说 isbn="1235" lang="zh"> <书名 hot="true">笑笑江湖</书名> <作者>金庸</作者> <价格>45</价格> <简介> <![CDATA[ 一本好书,没有<<笑傲江湖>>好看 ]]> </简介> </武侠小说> </书>
2.8 注释(xml和html相同)
1)格式: <!-- 这是一段注释 -->
2) 编译器将忽略注释
3) Html和xml注释方式相同
例子:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <书> 3 <!-- 这是一段注释 --> 4 <武侠小说 isbn="1001"> 5 <书名><<天龙八部>></书名> 6 <作者>金庸</作者> 7 <价格>50</价格> 8 <简介>一本好书</简介> 9 </武侠小说> 10 </书>
2.8 规则小结
1) 必须有唯一的根元素
2) xml标记大小写敏感
3) 标记必须配对出现,有开始有结束
4) 元素必须被正确嵌套
5) 属性必须有值,值必须用引号引起来
6) 如果遵循全部上述规则,称作well-formed文件(格式良好的xml文件)
2.9 使用XML文件描述数据的例子
1) 早期属性文件描述数据的方式
url = jdbd:oracle:thin@192.168.0.205:1521:dbsid
dbUser = openlab
dbPwd = open123
2) 现在使用xml表示方式
<?xml version="1.0" encoding="UTF-8"?> <书> <!-- 这是一段注释 --> <武侠小说 isbn="1001"> <书名><<天龙八部>></书名> <作者>金庸</作者> <价格>50</价格> <简介>一本好书</简介> </武侠小说> </书>
3. DTD/Schema
1) DTD/Schema:用来规范XML的标记规则
2) 有效的xml文件(valid xml file) = 格式良好的xml文件 + 有DTD或Schema规则 + 遵循DTD或Schema规则
3.1 DTD/Schema的作用
行业交换数据时要求xml文件格式相同,所以需要大家遵守规范的xml文件格式,比如两份xml文件要有相同的元素嵌套关系,相同的属性定义,相同的元素顺序,元素出现相同次数等
3.2文档类型定义DTD(Document Type Difinition)
1) DTD文档用来定义XML文件的格式,约束XML文件中的标记规则
2) DTD类型
PUBLIC(行业共用的)
SYSTEM(小范围自定义的)
3.2.1 DTD中的定义规则
必须列出所有节点,一个都不能少
1)元素
"*"星号 表示可以出现0-n次
"+"加号 表示可以出现1-n次
"|" 表示或(只能出现一个)
如(phone|mobile)表示固话或手机二选一
"?"问号: 表示出现0或1此
#PCDATA 表示字符串
2)属性:
定义在开始标记中的键值对
dtd 规则_属性
1) <!ATTLIST 标记名称 属性名称 属性类型>
2) isbn CDATA #REQUIRED: 表示isbn属性是必须的
3) isbn CDATA #IMPLIED: 表示isbn属性不是必须的
4) hot CDATA"false" :表示hot默认值是false
例子3.2.1
首先是dtd文件book.dtd
<!ELEMENT 书 (武侠小说, br)*> <!ELEMENT 武侠小说 (书名,作者+,价格,简介)> <!ELEMENT 书名 (#PCDATA)> <!ELEMENT 作者 (#PCDATA)> <!ELEMENT 价格 (#PCDATA)> <!ELEMENT 简介 (#PCDATA)> <!ELEMENT br EMPTY> <!ATTLIST 武侠小说 isbn CDATA #REQUIRED lang CDATA #IMPLIED> <!ATTLIST 书名 hot CDATA #IMPLIED>
在XML中使用
<?xml version="1.0"?> <!DOCTYPE 书 SYSTEM "book.dtd"> <书> <武侠小说 isbn="1234" lang="zh"> <书名 hot="false"><<天龙八部>></书名> <作者>金庸</作者> <作者>古龙</作者> <价格>45</价格> <简介>一本好书</简介> </武侠小说> <br></br> <武侠小说 isbn="1235" lang="zh"> <书名 hot="true">笑笑江湖</书名> <作者>金庸</作者> <价格>45</价格> <简介> <!-- 这是一段注释 --> <![CDATA[ 一本好书,没有<<笑傲江湖>>好看 CDATA中的所有特殊字符都不解释(原样显示) ]]> </简介> </武侠小说> <br></br> </书>
3.3 Schema ,DTD的升级版
与DTD的区别
1)命名空间(NameSpace)
XML文件允许自定义标记,所以可能出现来自不同源DTD或Schema文件的同名标记,为了区分这些标记,就需要使用命名空间.
命名空间的目的是有效的区分来自不同DTD的相同标记
比如xml中文件中使用了命名空间区分开"表格"和"桌则":
<html:table>
<line><column>这是一个表格</column></line>
</html;table>
<product:table>
<type>coff table</type>
<product:table>
2) 因为DTD无法解决命名冲突,所以出现Schema,它是DTD 的替代者,dtd和Schema的功能都是描述xml结构的
3) Schema使用xml语法实现(Schema本身就是xml文件)
因为用于规范和描述xml文件的定义文件(schema)本身也是xml文件,所也xml也被称为自描述的语言
4) Schema 文件的扩展名xds: XML Schema Difinition(简称XSD,遵循W3C标准)
5) Schema中的名词:
复杂元素(有子元素的元素)
简单元素(叶子元素)
例子:email.xsd
<?xml version="1.0" encoding="UTF-8"?> <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.example.org/email" xmlns:tns="http://www.example.org/email" elementFormDefault="qualified"> <element name="email"> <complexType> <sequence> <element name="from" type="string"/> <element name="to" type="string"/> <element name="subject" type="string"/> <element name="body" type="string" /> </sequence> </complexType> </element> </schema>
被规范的文件email.xml
<?xml version="1.0" encoding="UTF-8"?> <tns:email xmlns:tns="http://www.example.org/email" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.example.org/email email.xsd "> <tns:from>赵敏</tns:from> <tns:to>张无忌</tns:to> <tns:subject>HIHI</tns:subject> <tns:body>看泰坦尼克号</tns:body> </tns:email>
3.4 根据DTD或者Schema来写xml文件的方法
在MyEclipse中右键New --> xml (Basic Templates) -->输入文件名-->next-->选择是DTD还是Schema
4. java API 解析XML文件(读xml文件)
1) Java 与xml有很多共同点(比如跨平台,与厂商无关),目前位置java对xml的解析较其他语言更完善
2) 两种解析方式:
DOM(Document Object Model 文档对象模型)
关键字:树(Document)
优点: 把xml文件在内存中构造树形结构,可以遍历和修改节点
缺点: 如果文件比较大,内存有压力,解析的时间会比较长
SAX(Simple API for Xml基于XML的简单API)
关键字:流(Stream)
把xml文件作为输入流,触发标记开始,内容开始,标记结束等动作
优点:解析可以立即开始,速度快,没有内存压力
缺点:不能对节点做修改
3) JDOM/DOM4J : 目前市场上常用的两种解析XML文件的API
dom4j-1.6.1.jar 结合了DOM和SAX两种解析方式的优点
DOM4j解析xml文件步骤
1) 创建项目XMLDemo
2) 加入dom4j的jar包(dom4j-1.6-1.jar)
3) 将要解析的xml文件放在路径src/下
4) 新建ReadXMLDemo.java
4-1)构造document对象
SAXReader reader = new SAXReader();
Document doc = reader.read(file);
4-2)取根元素:
Element root = doc.getRootElement();
4-3)常用方法
Element elmt;
elmt.elements("标记名称"):取出所有指定标记名称的元素
elmt.element("标记名称"):取出第一个指定标记名称元素
elmt.elementText("标记名称"):取elmt指定名字的子元素
elmt.getText();取当前元素的内容
Iterator it = elmt.elementsIterator("标记名称") 返回一个Iterator
String 属性值 = elmt.attattributeValue("属性名")
例子:ReadBookdemo源代码
package day1; import java.io.*; import java.util.*; import org.dom4j.*; import org.dom4j.io.*; /** * 读入book.xml文件,取出数据并打印 * @author soft01 * */ public class ReadBookdemo { public static void main(String[] args) { readBook("book.xml"); } /** * 读入指定的xml文件,取出数据并打印 * @param string */ private static void readBook(String filename) { //1..读入指定的文件,构造Document对象 File file = new File(filename); SAXReader reader = new SAXReader();//XML文件解析器 try { Document doc = reader.read(file);//解析器开始解析xml文件 //2.获得根元素 Element root = doc.getRootElement(); //3.递归搜索子元素 /* List<Element> list = root.elements("武侠小说"); //迭代武侠小说的元素集合 Iterator<Element> it = list.iterator(); */ Iterator<Element> it = root.elementIterator("武侠小说"); while(it.hasNext()){ Element bookElmt = it.next(); //bookEmlt是武侠小说元素 //取武侠小说的子元素 System.out.println(bookElmt.elementText("书名"));//取 子元素 书名 的内容 List<Element> authorList = bookElmt.elements("作者"); for (Element element : authorList) { //打印 作者 元素内容 System.out.println(element.getText()); } System.out.println(bookElmt.elementText("价格")); System.out.println(bookElmt.elementText("简介")); //取 武侠小说 的 属性 String isbnValue = bookElmt.attributeValue("isbn"); //取 武侠小说 的 lang元素 String langValue = bookElmt.attributeValue("lang"); System.out.println("isbn="+isbnValue); System.out.println("lang="+langValue); //取子元素中的属性 Element nameElmt = bookElmt.element("书名"); System.out.println(nameElmt.attributeValue("hot")); System.out.println("-----------------"); } } catch (DocumentException e) { e.printStackTrace(); } } }
book.xml如下
<?xml version="1.0"?> <书> <武侠小说 isbn="1234" lang="zh"> <书名 hot="false"><<天龙八部>></书名> <作者>金庸</作者> <作者>古龙</作者> <价格>45</价格> <简介>一本好书</简介> </武侠小说> <br></br> <武侠小说 isbn="1235" lang="zh"> <书名 hot="true">笑笑江湖</书名> <作者>金庸</作者> <价格>45</价格> <简介> <!-- 这是一段注释 --> <![CDATA[ 一本好书,没有<<笑傲江湖>>好看 CDATA中的所有特殊字符都不解释(原样显示) ]]> </简介> </武侠小说> <br></br> </书>
5 DOM4j API解析XML文件(生成)
1)常用API方法:
给元素增加子元素: elmt.addElement("标记名称");
给元素增加属性: elmt.addAttribute("属性名","属性值");
给叶子元素设值: elmt.setText("元素值");
例如:
要生成以下xml文件
<book isbn="1001" catalog = "科幻"> <name>阿里波特</name> <author>罗林</author> <price>60</price> <year>2005</year> </book>
步骤:
1.构造空的Document
2.构造根元素
3.递归构造子元素
4.输出
WriteBookDemo源代码
package day1; import java.io.*; import org.dom4j.*; import org.dom4j.io.*; /** * 利用DOM4J写出xml文件 * @author soft01 * */ public class WriteBookDemo { static String [][] data={ {"1001", "科幻", "阿里波特", "罗林","60", "2005","en"}, {"1002", "迷幻", "小波特", "罗4林","60", "2005","zh"}, {"1003", "玄幻", "中波特", "罗3林","60", "2005","en"}, {"1004", "奇幻", "大波特", "罗2林","60", "2005","zh"} }; public static void main(String[] args) { writeBook("mybook.xml"); } /** * 把书的数据生成到指定名字的xml文件中 * @param filename */ public static void writeBook(String filename){ // 1.构造空的Document Document doc = DocumentHelper.createDocument(); // 2.构造根元素 Element rootElmt = doc.addElement("booklist"); // 3.递归构造子元素 for(String[] book:data){ Element bookElmt = rootElmt.addElement("book"); //book 元素增加属性 bookElmt.addAttribute("isbn", book[0]); bookElmt.addAttribute("catalog", book[1]); Element nameElmt = bookElmt.addElement("name"); nameElmt.setText(book[2]); //给name 加属性 nameElmt.addAttribute("lang", book[6]); Element authorElmt = bookElmt.addElement("author"); authorElmt.setText(book[3]); Element priceElmt = bookElmt.addElement("price"); priceElmt.setText(book[4]); Element yearElmt = bookElmt.addElement("year"); yearElmt.setText(book[5]); } // 4.输出 outputXml(doc,filename); } public static void outputXml(Document doc,String filename){ try { //定义输出流的目的地 FileWriter fw = new FileWriter(filename); //定义输出格式 和 字符集 OutputFormat format = OutputFormat.createPrettyPrint(); format.setEncoding("UTF-8"); //定义用于输出xml文件的XMLWriter对象 XMLWriter xmlWriter = new XMLWriter(fw,format); xmlWriter.write(doc); xmlWriter.close(); } catch (IOException e) { e.printStackTrace(); } } }
注意:运行程序生成的mybooks.xmlpackage day1;
不自动装载,需要刷新一下
程序运行通过后,在项目上点击右键"refreash"(或F5)
如果是从别的工作区导入的项目,需要去别的工作区目录下找生成的XML文件
6XPath(w3c的标准)
1) XPath:在XML文件中查找或定位信息的语言,相当于SQL中的 select
XPath 可以通过元素/属性/值来定位或导航
2) 节点(Node):相当于xml文件中的元素
3) 指定条件定位元素的方式
例子:
package day1; import java.io.*; import java.util.*; import org.dom4j.*; import org.dom4j.io.*; /** * 测试XPath的功能 * @author soft01 * */ public class XPathDemo { public static void main(String[] args) { findBook("mybook.xml"); } public static void findBook(String filename){ SAXReader reader = new SAXReader(); try { //获得文档对象 Document doc = reader.read(new File(filename)); Node node = doc.selectSingleNode("/booklist"); //查找所有的catalog="奇幻"的书2 //String sql = "book[@catalog ='奇幻']"; //价格>50的书 //String sql = "book[price>50]"; //作者等于罗林的书,并且价格大于50 //String sql ="book[author='罗林' and price>50]"; //价格大于50,且语言是zh String sql = "book[price>50 and name[@lang='zh']]"; List<Element> books = node.selectNodes(sql); for(Element e:books){ System.out.println(e.getStringValue()); } } catch (DocumentException e) { e.printStackTrace(); } } }