简介
XML指可扩展标记语言很类似 HTML,被设计用来传输和存储数据而非显示数据,XML标签没有被预定义需要自行定义标签,标签具有自我描述性,同时XML也是 W3C 的推荐标准。
xml定义方式
有两种定义形式,dtd文档类型定义和schema模式
本质区别:
schema本身是xml的,可以被XML解析器解析(这也是从DTD上发展schema的根本目的)
普通区别:
1.schema 是内容开放模型,可扩展,功能性强,而DTD可扩展性差。
2.shema 支持丰富的数据类型,而 DTD不支持元素的数据类型,对属性的类型定义也很有限。
3.schema 支持命名空间机制,而DTD不支持。
4.schema 可针对不同情况对整个XML 文档或文档局部进行验证;而 DTD缺乏这种灵活性。
5.schema 完全遵循XML规范,符合XML语法,可以和DOM结合使用,功能强大;而DTD 语法本身有自身的语法和要求,难以学习。
dtd:
内部dtd:在xml内部定义dtd
外部dtd:在外部文件中定义dtd
本地的dtd文件:<!DOCTYPE students SYSTEM “student.dtd”
网络的dtd文件:<!DOCTYPE students PUBLIC “名称空间(路径)” "student.dtd
<!ELEMENT students (student*)>
<!ELEMENT student (name,age,sex)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
<!ELEMENT sex (#PCDATA)>
<!ATTLIST student number ID #REQUIRED>
schema:
导入xsd约束文档:
?xml version="1.0"?>
<xsd:schema xmlns="http://www.kk.cn/xml"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.kk.cn/xml" elementFormDefault="qualified">
<xsd:element name="students" type="studentsType"/>
<xsd:complexType name="studentsType">
<xsd:sequence>
<xsd:element name="student" type="studentType" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="studentType">
<xsd:sequence>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="age" type="ageType" />
<xsd:element name="sex" type="sexType" />
</xsd:sequence>
<xsd:attribute name="number" type="numberType" use="required"/>
</xsd:complexType>
<xsd:simpleType name="sexType">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="male"/>
<xsd:enumeration value="female"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="ageType">
<xsd:restriction base="xsd:integer">
<xsd:minInclusive value="0"/>
<xsd:maxInclusive value="256"/>
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="numberType">
<xsd:restriction base="xsd:string">
<xsd:pattern value="kk_\d{4}"/>
</xsd:restriction>
</xsd:simpleType>
xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!--
1、编写根标签
2、引入实例名称空间 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3、引入名称空间 xsi:schemaLocation="http://www.itcast.cn/xml student.xsd"
4、引入默认的名称空间
<!DOCTYPE student SYSTEM "student.dtd">
-->
<students
xmlns="http://www.kk.cn/xml"
xsi:schemaLocation="http://www.kk.cn/xml student.xsd"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
>
<student number="kk_1001">
<name>asfd</name>
<age>12</age>
<sex>male</sex>
</student>
</students>
xml解析方式
-
DOM解析: DOM的全称是Document Object Model,也即文档对象模型。在应用程序中,基于DOM的XML分析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),应用程序正是通过对这个对象模型的操作,来实现对XML文档数据的操作。通过DOM接口,应用程序可以在任何时候访问XML文档中的任何一部分数据,因此,这种利用DOM接口的机制也被称作随机访问机制。
-
SAX解析:SAX的全称是Simple APIs for XML,也即XML简单应用程序接口。与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式。当使用SAX分析器对XML文档进行分析时,会触发一系列事件,并激活相应的事件处理函数,应用程序通过这些事件处理函数实现对XML文档的访问,因而SAX接口也被称作事件驱动接口。
-
JDOM解析:JDOM采用了Java中的Collection架构来封装集合,是Java爱好者更加熟悉的模式。
-
DOM4J解析:xml解析器一次性把整个xml文档加载进内存,然后在内存中构建一颗Document的对象树,通过Document对象,得到树上的节点对象,通过节点对象访问(操作)到xml文档的内容。
xml解析实例
解析文件book.xml , 以下给出代码示例
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book bookno="001">
<title>java</title>
<author>李白</author>
<price>80</price>
</book>
<book bookno="002">
<title>python</title>
<author>杜甫</author>
<price>100</price>
</book>
</books>
book实体 ,解析代码中通用的。
package xml.domparser;
/**
* @Auther: laughing
* @Date: 2019-3-5 16:28
* @Description: Book实体
*/
public class Book {
private String bookNo;
private String title;
private String author;
private Double price;
public Book() {
}
public Book(String bookNo, String title, String author, Double price) {
this.bookNo = bookNo;
this.title = title;
this.author = author;
this.price = price;
}
public String getBookNo() {
return bookNo;
}
public String getTitle() {
return title;
}
public String getAuthor() {
return author;
}
public Double getPrice() {
return price;
}
public void setBookNo(String bookNo) {
this.bookNo = bookNo;
}
public void setTitle(String title) {
this.title = title;
}
public void setAuthor(String author) {
this.author = author;
}
public void setPrice(Double price) {
this.price = price;
}
@Override
public String toString() {
return "Book{" +
"bookNo='" + bookNo + '\'' +
", title='" + title + '\'' +
", author='" + author + '\'' +
", price=" + price +
'}';
}
}
dom 解析
package xml.domparser;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @Auther: laughing
* @Date: 2019-3-5 16:27
* @Description: DOM解析XML文件
*/
public class DOMXMLParser {
public List<Book> parseXml(String fileName) {
List<Book> list = new ArrayList<>();
//文档生成器工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
Document document = null;
try {
/*文档生成器*/
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(new File(fileName));
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//根节点
Node rootNode = (Node) document.getDocumentElement();
/*获取<book>元素列表*/
NodeList bookElementList = rootNode.getChildNodes();
for (int i = 0; i < bookElementList.getLength(); i++) {
/*获取单个<book>元素*/
Node bookelement = (Node) bookElementList.item(i);
/*取节点名称*/
if (bookelement.getNodeName().equals("book")) {
Book book = new Book();
/*节点属性*/
NamedNodeMap map = bookelement.getAttributes();
Node booknoNode = (Node) map.getNamedItem("bookno");
String bookNoString = booknoNode.getNodeValue();
book.setBookNo(bookNoString.trim());
/*获取子节点*/
NodeList subBookElementList = bookelement.getChildNodes();
for (int j = 0; j < subBookElementList.getLength(); j++) {
/*子节点*/
Node subElemtNode = (Node) subBookElementList.item(j);
/*子节点元素名称*/
String subElementNameString = subElemtNode.getNodeName();
/*分析子节点元素名称从而获取内容*/
if (subElementNameString.equals("title")) {
/*获取节点内容*/
book.setTitle(subElemtNode.getTextContent().trim());
}
if (subElementNameString.equals("author")) {
/*获取节点内容*/
book.setAuthor(subElemtNode.getTextContent().trim());
}
if (subElementNameString.equals("price")) {
/*获取节点内容*/
book.setPrice(Double.parseDouble(subElemtNode.getTextContent().trim()));
}
}
list.add(book);
}
}
return list;
}
public static void main(String[] args) {
DOMXMLParser parser = new DOMXMLParser();
List<Book> list = parser.parseXml("book.xml");
System.out.println("DOM解析结果: ");
for (Book book : list) {
System.out.println(book);
}
}
}
sax解析
package xml.saxparser;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import java.util.ArrayList;
import java.util.List;
/**
* @Auther: laughing
* @Date: 2019-3-5 17:19
* @Description: sax解析器
*/
public class XMLHandler extends DefaultHandler {
private List<Book> list;
private Book book;
private String tag;
public XMLHandler() {
super();
}
// 返回解析到的集合。
public List<Book> getList() {
return list;
}
/**
* 文档解析开始,初始化集合
*
* @throws SAXException
*/
@Override
public void startDocument() throws SAXException {
System.out.println("文档解析开始--");
list = new ArrayList<Book>();
}
/**
* 文档解析结束
*
* @throws SAXException
*/
@Override
public void endDocument() throws SAXException {
System.out.println("文档解析结束--");
}
// 开始标记
// qName;表示标签名
// attributes:属性集合
/**
* 开始标记
*
* @param uri
* @param localName
* @param qName 标签名字
* @param attributes 属性集合
* @throws SAXException
* 主要来处理标签上的属性
*/
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
tag = qName;
if ("book".equals(tag)) {
this.book = new Book();
for (int i = 0; i < attributes.getLength(); i++) {
String q = attributes.getQName(i);
String v = attributes.getValue(i);
if ("bookno".equals(q)) {
book.setBookNo(v);
}
}
}
}
/**
* 结束标记 把处理的对象放到list中
*
* @param uri
* @param localName
* @param qName
* @throws SAXException
*/
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if ("book".equals(qName)) {
list.add(book);
}
tag = "";
}
// 标记与标记之间的内容
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
String str = new String(ch, start, length);
// 判断标记
if ("title".equals(tag)) {
book.setTitle(str);
} else if ("author".equals(tag)) {
book.setAuthor(str);
} else if ("price".equals(tag)) {
book.setPrice(Double.valueOf(str));
}
}
public static void main(String[] args) throws Exception {
//得到解析工厂。
SAXParserFactory factory = SAXParserFactory.newInstance();
//通过工厂得到解析器。
SAXParser parser = factory.newSAXParser();
XMLHandler handler = new XMLHandler();
//将文件和Handler,和解析器相关联。
parser.parse("book.xml", handler);
//需要得到解析后的集合。
List<Book> list = handler.getList();
for (Book s : list) {
System.out.println(s);
}
}
}
JDOM解析
需要依赖
<dependency>
<groupId>jdom</groupId>
<artifactId>jdom</artifactId>
<version>1.0</version>
</dependency>
package xml.jdomparser;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import java.io.IOException;
import java.util.List;
/**
* @Auther: laughing
* @Date: 2019-3-5 17:52
* @Description: jdom 解析
*/
public class JdomParser {
public static void main(String[] args) throws Exception {
parser();
}
private static void parser() throws JDOMException, IOException {
SAXBuilder saxBuilder = new SAXBuilder();
Document doc = saxBuilder.build("book.xml");
// 获取根元素
Element rootElement = doc.getRootElement();
// 取名字为book的所有元素
List list = rootElement.getChildren("book");
for (int i = 0; i < list.size(); i++) {
Element element = (Element) list.get(i);
// 获取元素中属性为name的值
String bookno = element.getAttributeValue("bookno");
// 取disk子元素capacity的内容
String title = element.getChildText("title");
String author = element.getChildText("author");
String price = element.getChildText("price");
System.out.println(bookno + "-" + title + "-" + author + "-" + price);
}
}
}
DOM4J解析
package xml.dom4j;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.util.List;
/**
* @Auther: laughing
* @Date: 2019-3-5 18:19
* @Description: dom4j解析xml 创建 xml
*/
public class Dom4jparser {
public static void main(String[] args) throws Exception {
// parser();
write();
}
private static void parser() throws DocumentException {
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("book.xml");
//根节点
Element rootElement = document.getRootElement();
//孩子们
List<Element> elements = rootElement.elements("book");
for (Element child : elements) {
String bookNo = child.attributeValue("bookno");
String title = child.elementText("title");
String author = child.elementText("author");
String price = child.elementText("price");
System.out.println(bookNo + "-" + title + "-" + author + "-" + price);
}
}
private static void write() throws Exception {
Document doc = DocumentHelper.createDocument();
Element books = doc.addElement("books");
Element book1 = books.addElement("book");
Element title1 = book1.addElement("title");
Element author1 = book1.addElement("author");
Element price1 = book1.addElement("price");
book1.addAttribute("bookno", "001");
title1.setText("java");
author1.setText("李白");
price1.setText("10");
Element book2 = books.addElement("book");
Element title2 = book2.addElement("title");
Element author2 = book2.addElement("author");
Element price2 = book2.addElement("price");
book2.addAttribute("bookno", "002");
title2.setText("java2");
author2.setText("李白2");
price2.setText("102");
//格式化输出
OutputFormat format = OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
File file = new File("book1.xml");
//写文件
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(file), format);
xmlWriter.write(doc);
}
}