只是小人物

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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 --> &lt;


2) 大于号(>) : great than --> &gt;


3) And符号(&) :  &amp;


4) 双引号 ( ") : &quot;


5) 单引号( ') : &apos;


注意这些转义字符都是以&开头,以 ; 结尾

例如:想给天龙八部加上书名号<<天龙八部>>

<?xml version="1.0" encoding="UTF-8"?>
<>
 <武侠小说 isbn="1001">
  <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
  <作者>金庸</作者>
  <价格>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   <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
 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">
  <书名>&lt;&lt;天龙八部&gt;&gt;</书名>
  <作者>金庸</作者>
  <价格>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">&lt;&lt;天龙八部&gt;&gt;</书名>
  <作者>金庸</作者>
  <作者>古龙</作者>
  <价格>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">&lt;&lt;天龙八部&gt;&gt;</书名>
  <作者>金庸</作者>
  <作者>古龙</作者>
  <价格>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();
  }
 }
}

 

 

posted on 2012-05-16 00:25  只是小人物  阅读(6228)  评论(1编辑  收藏  举报