1.XML概念和体系
1.1XML概念
XML指可扩展标记语言
XML没有预定义标签,需要自行定义标签
1.2XML的特点
XML数据以纯文本格式存储
实现不同应用程序之间的数据通信
实现不同平台的数据通信
实现不同平台的数据共享
使用XML将不同的程序、不同的平台之间联系起来
1.3XML的作用
数据存储和数据传输
1.4XML和HTML之间的差异
XML主要作用是数据存储和传输
HTML主要作用是用来显示数据
1.5一个标准的XML文档
1.6XML文件的体系
- XHTML 可扩展标识语言
- WSDL Web Services Description Language 网络服务描述语言,这种文档可描述某个 Web service
- WAP 和 WML 手持设备的标记语言
- RSS( 广 泛 用 于 网 上 新 闻 频 道 ) : Really Simple Syndication 简易信息聚合,使用 RSS 订阅能更快地获取 信息,网站提供 RSS 输出,有利于让用户获取网站内容 的最新更新
- RDF 和 OWL: 重要的语义网技术语义网是为资产管理、 企业整合及网络数据的共享和重用提供的一个框架。
- SMIL 同步多媒体集成语言,它是由万维网联盟规定的多 媒体操纵语言。最新的 SMIL 版本是 2001 年 8 月推出的 SMIL 2.0 版本,它通过时序排列对声音、影像、文字及图 形文件进行顺序安排,然后将这些媒体表现看起来是同步 的.
2.XML基本语法
2.1XML的基本语法
(1)有且只有一个根元素
(2)XML文档声明必须放在文档的第一行
(3)所有标签必须成对出现
(4)XML的标签严格区分大小写
(5)XML必须正确嵌套
(6)XML中的属性值必须加引号
(7)XML中,一些特殊字符需要使用“实体”
(8)XML中可以应用适当的注释
2.2XML元素
XML元素指的是开始标签到结束标签的部分
一个元素中可以包含
(1)其他元素
(2)文本
(3)属性
(4)以上的混合
2.3XML命名规则
(1)名称可以包含字母、数字及其他字符
(2)名称不能以数字或者标点符号开始
(3)名称不能以字母xml开始
(4)名称不能包含空格
<?xml version="1.0" encoding="UTF-8"?><!--文档声明,必须放在第一行 -->
<books>
<book id="1001">
<name>java开发实战</name>
<author>张小三</author>
<price>98.5</price>
</book>
</books>
3.Schema技术
3.1DTD验证
概念:DTD文档类型定义
作用:验证是否是“有效”得XML
<?xml version="1.0" encoding="UTF-8"?>
<!-- <!DOCTYPE books [
<!ELEMENT books (book*)>
<!ELEMENT book (name,author,price)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT author (#PCDATA)>
<!ELEMENT price (#PCDATA)>
<!ATTLIST book id CDATA #REQUIRED>
]>-->
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="{book.xsd}">
<book id="1001">
<name>java开发实战</name>
<author>张小三</author>
<price>98.5</price>
</book>
<book id="1002">
<name>mysql从删库到跑路</name>
<author>王一一</author>
<price>89.7</price>
</book>
</books>
PCDATA的意思是被解析的字符数据
CDATA不应由XML解析器进行解析的文本数据
使用DTD的局限性
(1)DTD不遵守XML语法
(2)DTD数据类型有限
(3)DTD不可扩展
(4)DTD不支持命名空间
3.2Schema技术
Schema是DTD的代替者,名称为XML Schema,用于描述XML文档结构,比DTD更加强大,最主要的特征之一就是XML Schema支持数据类型
(1)Schema使用XML验证XML遵循XML的语法
(2)Schema可以用能处理XML文档的工具处理
(3)Schema大大扩充了数据类型,而且还可以自定义数据类型
(4)Schema支持元素的继承
(5)Schema支持属性组
3.3Schema的文档结构
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" >
</xs:schema>
所有的Schema文档使用schema作为其根元素http://www.w3.org/2001/XMLSchema:用于验证当前Schema文档的命名空间(用于验证Schema本身),同时它还规定了来自命名空间http://www.w3.org/2001/XMLSchema的元素和数据类型应该使用前缀xs:
xmlns相当于java中的import,:xs“小名”,在使用时要写加“小名”做前缀
(XML使用Schema验证,那Schema也是一个XML,谁来验证它?DTD)
<?xml version="1.0" encoding="UTF-8"?>
<books xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="{book.xsd}">
<book id="1001">
<name>Java开发实战</name>
<author>张小三</author>
<price>98.5</price>
</book>
<book id="1002">
<name>mysql从删库到跑路</name>
<author>王一一</author>
<price>89.7</price>
</book>
</books>
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="books">
<xs:complexType>
<xs:sequence>
<xs:element name="book" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="name" type="xs:string"></xs:element>
<xs:element name="author" type="xs:string"></xs:element>
<xs:element name="price" type="xs:double"></xs:element>
</xs:sequence>
<xs:attribute name="id" type="xs:positiveInteger" use="required"></xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
3.3使用Schema验证XML文档
- 创建SchemaFactory工厂
- 建立验证文件对象
- 利用SchemaFactory工厂对象,接受验证的文件对象,生成Schema对象
- 产生对此schema的验证器
- 要验证的数据(准备数据源)
- 开始验证
import java.io.File;
import java.io.IOException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;
import org.xml.sax.SAXException;
public class Test {
public static void main(String[] args) throws SAXException {
//(1)创建SchemaFactory工厂
SchemaFactory sch = SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
//(2)建立验证文件对象
File schemaFile = new File("book.xsd");
//(3)利用SchemaFactory工厂对象,接受验证的文件对象,生成Schema对象
Schema schema = sch.newSchema(schemaFile);
//(4)产生对比schema的验证器
Validator validator = schema.newValidator();
//(5)要验证的数据(准备数据源)
Source source = new StreamSource("book.xml");
//(6)开始验证
try {
validator.validate(source);
System.out.println("成功");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("失败");
}
}
}
4.DOM方式解析XML数据
在Java程序中读取XML文件的过程称为解析XML
4.1解析XML文件的方式
(1)DOM解析(java官方提供)
(2)SAX解析(java官方提供)
(3)JDOM解析(第三方提供)
(4)DOM4J解析(第三方提供)
4.2DOM解析XML的步骤
(1)创建一个DocumentBuilderFactory的对象
(2)创建一个DocumentBuilder对象
(3)通过DocumentBuilder的parse(…)方法得到Document对象
(4)通过getElementsByTagName(…)方法获取到节点的列表
(5)通过for循环遍历每一个节点
(6)得到每个节点的属性和属性值
(7)得到每个节点的节点名和节点值
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class TestDOMParse {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//(1)创建一个DocumentBuilderFactory的对象
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
//(2)创建一个DocumentBuilder对象
DocumentBuilder db = dbf.newDocumentBuilder();
//(3)通过DocumentBuilder的parse(...)方法得到Document对象
Document doc= db.parse("book.xml");
//(4)通过getElementsByTagName(...)方法获取到节点的列表
NodeList bookList = doc.getElementsByTagName("book");
//(5)通过for循环遍历每一个节点
for(int i = 0;i<bookList.getLength();i++) {
Node book = bookList.item(i);
NamedNodeMap attrs = book.getAttributes();//得到了属性的集合
//循环遍历每一个属性
for(int j=0;j<attrs.getLength();j++) {
//得到每一个属性
Node id = attrs.item(j);
System.out.println("属性的名称:"+id.getNodeName()+"\t"+id.getNodeValue());
}
}
System.out.println("\n每个节点的名和节点的值");
for(int i = 0;i<bookList.getLength();i++) {
//得到每一个book节点
Node book = bookList.item(i);
NodeList subNode = book.getChildNodes();
System.out.println("子节点的个数:"+subNode.getLength());
//使用for循环遍历每一个book的子节点
for(int j = 0;j<subNode.getLength();j++) {
Node childNode = subNode.item(j);
short type=childNode.getNodeType();
if(type==Node.ELEMENT_NODE) {
System.out.println("节点的名称:"+childNode.getNodeName()+"\t"+childNode.getTextContent());
}
}
}
}
}
5.SAX方式解析XML数据
5.1SAX的概述
SAX,全称Simple API for XML,是一种以事件驱动的XML API,SAX与DOM不同的是它边扫描边解析,自顶向下依次解析,由于边扫描边解析,所以它解析XML具有速度快,占用内存少的优点。
5.2SAX解析XML的步骤
(1)创建SAXParserFactory的对象
(2)创建SAXParser对象(解析器)
(3)创建一个DefaultHandler的子类
(4)调用parse方法
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.SAXException;
public class TestSAXParse {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//(1)创建SAXParserFactory的对象
SAXParserFactory spf = SAXParserFactory.newInstance();
//(2)创建SAXParser对象(解析器)
SAXParser parser = spf.newSAXParser();
//(3)创建一个DefaultHandler的子类
BookDeaultHanler bdh = new BookDeaultHanler();
//(4)调用parse方法
parser.parse("book.xml", bdh);
}
}
import javax.xml.stream.events.StartDocument;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class BookDeaultHanler extends DefaultHandler{
//重写第一个方法
/**解析xml文档时调用*/
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
super.startDocument();
System.out.println("解析xml文档开始");
}
/**解析xml文档结束时调用*/
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
super.endDocument();
System.out.println("解析xml文档结束");
}
/**解析xml文档中的节点时调用*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
/**判断,如果是book节点,获取节点的属性和属性值*/
if("book".equals(qName)) {
int count = attributes.getLength();//属性的个数
//循环获取每个属性
for(int i = 0;i < count;i++) {
String attName = attributes.getQName(i);//属性名称
String attValue = attributes.getValue(i);//属性值
System.out.println("属性名称"+attName+"\t属性值为:"+attValue);
}
}else if(!"books".equals(qName)&&!"book".equals(qName)) {
System.out.print("节点的名称:"+qName+"\t");
}
}
/**解析xml文档中的节点结束时调用*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
String value = new String(ch,start,length);
if(!"".equals(value.trim())) {
System.out.println(value);
}
}
}
6.JDOM解析XML数据
6.1JDOM概述
JDOM是一种解析XML的Java工具包,它基于树型结构,利用纯Java的技术对XML文档实现解析。所以只适合于Java语言。
6.2JDOM解析XML的步骤
(1)创建一个SAXBuilder对象
(2)调用build方法,得到Document对象(通过IO流)
(3)获取根节点
(4)获取根节点的直接子节点的集合
(5)遍历集合
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.List;
import org.jdom.Attribute;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
public class TestJDOM {
public static void main(String[] args) throws FileNotFoundException, JDOMException, IOException {
//(1)创建一个SAXBuilder对象
SAXBuilder sb = new SAXBuilder();
//(2)调用build方法,得到Document对象(通过IO流)
Document doc = sb.build(new FileInputStream("book.xml"));
//(3)获取根节点
Element root = doc.getRootElement();
//(4)获取根节点的直接子节点的集合
List<Element> bookEle = root.getChildren();
//(5)遍历集合,得到book的每一个子节点(子元素)
for (int i = 0;i < bookEle.size();i++) {
Element book = bookEle.get(i);
//得到属性集合
List<Attribute> attList = book.getAttributes();
//遍历属性的集合得到每一个属性
for (Attribute attr : attList) {
System.out.println(attr.getName()+"\t"+attr.getValue());
}
}
//得到每一个子节点
System.out.println("\n----------------------");
for(int i = 0;i<bookEle.size();i++) {
Element book = bookEle.get(i);//得到每一个book节点
List<Element> subBook = book.getChildren();
//遍历每一个节点,获取节点名称节点值
for (Element ele : subBook) {
System.out.println(ele.getName()+"\t"+ele.getValue());
}
System.out.println("================================");
}
}
}
7.DOM4J方式解析XML数据
DOM4J是一个Java的XML API,是JDOM的升级品,用来读写XML文件的。
7.1DOM4J解析XML的步骤
(1)创建SAXReader对象
(2)调用read方法
(3)获取根元素
(4)通过迭代器遍历直接节点
public class Book {
private String name;
private String author;
private double price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public Book(String name, String author, double price) {
super();
this.name = name;
this.author = author;
this.price = price;
}
public Book() {
super();
}
}
import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import com.java.entity.Book;
public class TestDOM4J {
public static void main(String[] args) throws DocumentException {
//(1)创建SAXReader对象
SAXReader reader = new SAXReader();
//(2)调用read方法
Document doc = reader.read(new File("book.xml"));
//(3)获取根元素
Element root = doc.getRootElement();
//(4)通过迭代器遍历直接节点
for(Iterator<Element> iteBook = root.elementIterator();iteBook.hasNext();) {
Element bookEle = iteBook.next();
//System.out.println(bookEle.getName());
//得到book的属性
for(Iterator<Attribute> iteAtt = bookEle.attributeIterator();iteAtt.hasNext();) {
Attribute att = iteAtt.next();
System.out.println(att.getName()+"\t"+att.getText());
}
}
List<Book> bookList = new ArrayList<Book>();
System.out.println("\n-------------------");
for(Iterator<Element> iteBook = root.elementIterator();iteBook.hasNext();) {
//创建Book对象
Book book = new Book();
Element bookEle = iteBook.next();//得到每一个book
//使用for循环继续遍历
for(Iterator<Element> subBookEle = bookEle.elementIterator();subBookEle.hasNext();) {
//得到每一个子元素
Element subEle = subBookEle.next();
System.out.println(subEle.getName()+"\t"+subEle.getText());
/**
* 封装成Book对象
*/
//获取节点的名称
String nodeName = subEle.getName();
//使用switch判断
switch (nodeName) {
case "name":
book.setName(subEle.getText());
break;
case "author":
book.setAuthor(subEle.getText());
break;
case "price":
book.setPrice(Double.parseDouble(subEle.getText()));
break;
}
}
//添加到集合中
bookList.add(book);
}
//遍历集合
System.out.println("\n遍历集合-----------------");
for(Book b:bookList) {
System.out.println(b.getName()+"\t"+b.getAuthor()+"\t"+b.getPrice());
}
}
}
7.2四种解析XML的特点
(1)DOM解析:
形成了树结构,有助于更好的理解、掌握,且代码容易编写。
解析过程中,树结构保存在内存中,方便修改。
(2)SAX解析:
采用事件驱动模式,对内存耗费比较小。
适用于只处理XML文件中的数据时。
(3)JDOM解析:
仅适用具体类,而不使用接口。
API大量使用了Collections类
(4)DOM4J解析:
JDOM的一种智能分支,它合并了许多超出基本XML文档表示的功能。
它使用接口和抽象基本类方法。
具有性能优异、灵活性好、功能强大和极端易用的特点。
是一个开放源码的文件。
8.XPATH技术_快速获取节点
8.1准备资源
(1)DOM4J的jar包
(2)Jaxen的jar包
(3)Xpath中文文档
public class Test {
public static void main(String[] args) throws DocumentException {
//(1)SAXReader对象
SAXReader reader = new SAXReader();
//(2)读取XML文件
Document doc = reader.read("book.xml");
//得到第一个author节点
Node node = doc.selectSingleNode("//author");
System.out.println("节点的名称:"+node.getName()+"\t"+node.getText());
//获取所有的author
System.out.println("\n------------------");
List<Node> list = doc.selectNodes("//author");
for (Node n : list) {
System.out.println("节点名称:" + n.getName()+"\t"+n.getText());
}
//选择有id属性的book元素
List<Attribute> attList = doc.selectNodes("/book/@id");
for (Attribute att : attList) {
System.out.println("属性的名称:"+att.getName()+"\t"+att.getText());
}
}
}