1.CDATA区
在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理。
遇到此种情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。
语法:<![CDATA[ 内容 ]]>
<![CDATA[
<book>
<br/>
</book>
]]>
2.处理指令
处理指令,简称PI (processing instruction)。处理指令用来指挥解析引擎如何解析XML文档内容。
例如,在XML文档中可以使用xml-stylesheet指令,通知XML解析引擎,应用css文件显示xml文档内容。说白了,就是xml使用样式 <?xml-stylesheet type="text/css" href="1.css"?>
处理指令必须以“<?”作为开头,以“?>”作为结尾,XML声明语句就是最常见的一种处理指令。
3.XML约束概述
什么是XML约束
在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束。
常用的约束技术
(1)XML DTD
DTD(Document Type Definition),全称为文档类型定义,就是通过dtd文件来约束xml文档的节点、属性等书写。
(2)XML Schema,是基于xml的DTD替代者。
XML Schema 文件自身就是一个XML文件,但它的扩展名通常为.xsd
和XML文件一样,一个XML Schema文档也必须有一个根结点,但这个根元素的名称为Schema
XML Schema是用一套预先规定的XML元素和属性创建的,这些元素和属性定义了XML文档的结构和内容模式。 XML Schema规定XML文档实例的结构和每个元素/属性的数据类型
4.JavaBean
就是一个实体类,自定义对象,需要有一组get和set方法,必须存在默认的构造函数
5.XML解析
XML解析技术概述
XML解析方式分为两种:dom和sax
dom:(Document Object Model, 即文档对象模型) 是 W3C 组织推荐的解析XML 的一种方式。
sax: (Simple API for XML) 不是官方标准,但它是 XML 社区事实上的标准,几乎所有的 XML 解析器都支持它。
XML解析器
Crimson(sun)、Xerces(IBM)、Aelfred2(dom4j)
XML解析开发包
Jaxp(sun)、Jdom、dom4j、pull(android的sdk自带)
(1)JAXP-DOM解析xml(CURD)
JAXP(Java API for XML Processing )
JAXP是 Sun 提供的一套XML解析API
JAXP很好的支持DOM和SAX解析方式
JAXP 开发包是J2SE的一部分,包括以下包或子包
javax.xml
org.w3c.dom
org.xml.sax
在 javax.xml.parsers 包中,定义了几个工厂类,程序员调用这些工厂类,可以得到对xml文档进行解析的 DOM 或 SAX 的解析器对象
Book.java
package com.yxl.xml;
/**
* 自定义对象 --JavaBean
* * 需要有一组特殊的方法:getXxx 和 setXxx
* * 必须存在默认的构造方法
*
* alt + shift + s
*/
public class Book {
private String id;
private String title;
private String price;
public String getId(){
return this.id;
}
public void setId(String id){
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public Book() {
}
public Book(String id, String title, String price) {
this.id = id;
this.title = title;
this.price = price;
}
@Override
public String toString() {
return "Book [id=" + id + ", price=" + price + ", title=" + title + "]";
}
}
books.xml
<?xml version="1.0" encoding="UTF-8"?>
<books>
<book id="b001">
<title>Java 核心技术</title>
<price>98000</price>
</book>
<book id="b002">
<title>Thinking in Java</title>
<price>22000</price>
</book>
</books>
查询
package com.yxl.xml;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class MainClass {
public static void main(String[] args) throws Exception {
System.out.println(getAllBook());
}
/*
* 获得所有的书籍,将所有的书籍内容保存list
*/
public static List getAllBook() throws Exception{
//创建list,用于保存所有的数据
List allBookList = new ArrayList();
/* 从xml文档中将需要的数据,查询出来,替换模拟数据 */
//获得实例工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获得解析
DocumentBuilder builder = factory.newDocumentBuilder();
//获得document --解析xml文档 java.io.FileNotFoundException
Document document = builder.parse("books.xml"); //指java项目的根路径下的文件
//获得所有的书籍元素
NodeList bookElements = document.getElementsByTagName("book");
//遍历所有的书籍元素
for(int i = 0 ; i < bookElements.getLength() ; i++){
//获得每一本书籍元素
Node node = bookElements.item(i);
// node.getAttributes(); --获得所有的属性
Element bookEle = (Element)node;
//获得指定名称id,的属性值
String id = bookEle.getAttribute("id");
String title = "";
String price = "";
//将title和price查询
//获得当前book元素的所有的子节点
NodeList childList = bookEle.getChildNodes();
System.out.println( id + ":" + childList.getLength());
//遍历所有的孩子
for(int c = 0 ; c < childList.getLength() ; c++){
//获得所有的孩子
Node childNode = childList.item(c);
//Element child = (Element)childNode; //java.lang.ClassCastException:
//获得节点名称
String childName = childNode.getNodeName();
//判断是否title
//if(childName.equals("title"))
if("title".equals(childName)){
//获得title内容
title = childNode.getTextContent();
}
//判断是否是price
if("price".equals(childName)){
price = childNode.getTextContent();
}
}
//创建JavaBean Book对象
Book book = new Book();
book.setId(id);
book.setPrice(price);
book.setTitle(title);
//将保存所有数据的对象Book添加到list中
allBookList.add(book);
}
return allBookList;
}
}
增删改
package com.yxl.xml;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
public class CUDTest {
public static void main(String[] args) throws Exception{
//将内存中的document,另存到books.jasp.xml文件中
Document document = CUDTest.getDocument();
//将document的内容修改:添加、删除、修改
//添加
/* 添加的内容
* <book id="b002">
<title>Thinking in Java</title>
<price>22000</price>
</book>
* 给谁添加:根元素 books
*/
//获得books根元素
Element rootElement = document.getDocumentElement();
//创建book元素
Element newBook = document.createElement("book");
//设置id属性
newBook.setAttribute("id", "b003");
//创建title元素
Element titleElement = document.createElement("title");
//将title元素,添加到新book元素中
newBook.appendChild(titleElement);
//给title添加值
titleElement.setTextContent("凤姐写真");
//将book元素添加到books根元素中
rootElement.appendChild(newBook);
//保存
saveXml(document);
}
private void delete() throws Exception{
//将内存中的document,另存到books.jasp.xml文件中
Document document = CUDTest.getDocument();
//将document的内容修改:添加、删除、修改
//删除 <book id="b001">
//获得所有的书籍
NodeList bookList = document.getElementsByTagName("book");
for(int n = 0 ; n < bookList.getLength() ; n ++){
//获得每一本书
Node bookNode = bookList.item(n);
//获得id的值
Element bookElement = (Element) bookNode;
String id = bookElement.getAttribute("id");
//判断book id == b001
if("b001".equals(id)){
//删除 bookElement 当前节点,调用父节点,进行操作
//获得父节点
Node parent = bookElement.getParentNode();
//操作
parent.removeChild(bookElement);
}
}
//保存
saveXml(document);
}
private void update() throws Exception{
//将内存中的document,另存到books.jasp.xml文件中
Document document = CUDTest.getDocument();
//将document的内容修改:添加、删除、修改
//修改 <book id="b001"><title>Java 核心技术</title> --》 Java Core
//获得所有的书籍
NodeList bookList = document.getElementsByTagName("book");
for(int n = 0 ; n < bookList.getLength() ; n ++){
//获得每一本书
Node bookNode = bookList.item(n);
//获得id的值
Element bookElement = (Element) bookNode;
String id = bookElement.getAttribute("id");
//判断book id == b001
if("b001".equals(id)){
//获得所有的title
NodeList childList = bookElement.getElementsByTagName("title");
//获得唯一一个title
Node title = childList.item(0);
//获得title
System.out.println(title.getTextContent());
//设置值
title.setTextContent("Java Core");
}
}
//保存
saveXml(document);
}
private static void saveXml(Document document) throws Exception {
//获得持久化对象实例工厂
TransformerFactory factory = TransformerFactory.newInstance();
//获得持久化对象
Transformer transformer = factory.newTransformer();
//将内存数据,保存到硬盘
//源:document 将document封装到Source
Source xmlSource = new DOMSource(document);
//结果:books.jasp.xml 将“文件路径”封装到Result
Result outputTarget = new StreamResult("books.jasp.xml");
transformer.transform(xmlSource, outputTarget);
System.out.println("done");
}
/**
* 获得document对象
* @return
*/
public static Document getDocument() throws Exception{
//获得工厂实例
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//获得解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//获得document
Document document = builder.parse("books.xml");
return document;
}
}
(2)JAXP-SAX解析xml
SAX解析原理
SAX 是事件驱动的 XML 处理方法
逐行扫描文档,一边扫描一边解析
SAX来说就是操作复杂
仅需实现部分接口时扩展org.xml.sax.helpers.DefaultHandler类
DefaultHandler类默认的空实现
SaxTest.java
package com.yxl.xml;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.helpers.DefaultHandler;
public class SaxTest {
public static void main(String[] args) throws Exception {
//获得解析工厂实例
SAXParserFactory factory = SAXParserFactory.newInstance();
//获得解析器
SAXParser parser = factory.newSAXParser();
DefaultHandler dh = new MyDefaultHandler();
//解析xml文档
parser.parse("books.xml", dh);
System.out.println("done");
}
}
MyDefaultHandler.java
package com.yxl.xml;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class MyDefaultHandler extends DefaultHandler{
@Override
public void startDocument() throws SAXException {
System.out.println("文档开始");
}
@Override
/**
* 如果xml文件使用了schema约束 <xs:element>
* * uri:schema -- targetNameSpace
* * localName--element
* * qName---xs:element
* 如果不使用
* * uri:null
* * localName:null
* * qName : element
*
* Attributes:当前元素的所有的属性的集合
*/
public void startElement(String uri, String localName, String qName,
Attributes attributes) throws SAXException {
System.out.println("元素开始" + qName + " *** " + attributes.getValue("id"));
}
@Override
public void characters(char[] ch, int start, int length)
throws SAXException {
System.out.println(new String(ch ,start, length));
}
@Override
public void endElement(String uri, String localName, String qName)
throws SAXException {
System.out.println("元素结束:" + qName);
}
@Override
public void endDocument() throws SAXException {
System.out.println("文档结束");
}
}
(3)Dom4j解析xml,开发推荐使用这种
Dom4j是一个简单、灵活的开放源代码的库。Dom4j是由早期开发JDOM的人分离出来而后独立开发的。与JDOM不同的是,dom4j使用接口和抽象基类,虽然Dom4j的API相对要复杂一些,但它提供了比JDOM更好的灵活性
Dom4j是一个非常优秀的Java XML API,具有性能优异、功能强大和极易使用的特点。现在很多软件采用的Dom4j,例如Hibernate,包括sun公司自己的JAXM也用了Dom4j
使用Dom4j开发,需下载dom4j相应的jar文件
引用jar包方法,在项目根目录下新建文件夹名为lib,将要使用的jar包复制到该文件夹中,对着要使用的jar包右击Build Path,Add To Build Path
XML查询,引用dom4j-1.6.1.jar
Dom4jTest.java
package com.yxl.xml;
import java.util.ArrayList;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class Dom4jTest {
public static void main(String[] args) throws Exception {
//需要List 存放所有的book对象
List allBook = new ArrayList();
//获得解析流
SAXReader reader = new SAXReader();
//xml文件的解析
Document document = reader.read("books.xml");
//获得根元素
Element rootElement = document.getRootElement();
//获得所有的书籍
List list = rootElement.elements();
//遍历所有的书籍 -- list
for(int e = 0 ; e < list.size() ; e ++){
//创建book对象
Book book = new Book();
//获得每一本book元素
Element bookElement = (Element)list.get(e);
//获得书籍的id属性值
String id = bookElement.attributeValue("id");
//System.out.println(id);
book.setId(id);
//获得title和price
List childList = bookElement.elements();
//遍历子元素
for(int c = 0 ; c < childList.size() ; c ++){
//获得每一个子元素
Element child = (Element) childList.get(c);
// System.out.println(child);
//获得子元素文本内容
String content = child.getText();
//判断是否是title
if("title".equals(child.getName())){
book.setTitle(content);
}
//判断是否是price
if("price".equals(child.getName())){
book.setPrice(content);
}
}
//将已经封装了内容的book对象,添加到list中
allBook.add(book);
}
//程序解析前,输出内容
System.out.println(allBook);
}
}
XML查询,使用xpath表达式查询,引用dom4j-1.6.1.jar、jaxen-1.1-beta-6.jar
XPathTest.java
package com.yxl.xml;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class XPathTest {
public static void main(String[] args) throws Exception {
//获得document
//获得解析流
SAXReader reader = new SAXReader();
//解析xml
Document document = reader.read("books.xml");
//查询book id = b002 的元素 java.lang.NoClassDefFoundError
Node node = document.selectSingleNode("//book[@id='b002']");
System.out.println(node);
}
}
dom4j增删改
package com.yxl.xml;
import java.io.FileOutputStream;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;
public class CURDTest {
public static void main(String[] args) throws Exception {
//获得document
//获得解析流
SAXReader reader = new SAXReader();
//解析xml
Document document = reader.read("books.xml");
//获得根元素
Element rootElement = document.getRootElement();
//添加
//创建book元素
Element newBook = DocumentHelper.createElement("book");
//创建book元素的id属性
Attribute idAttr = DocumentHelper.createAttribute(newBook, "id", "b004");
//添加到book元素中
newBook.add(idAttr);
//创建title元素
Element titleElement = DocumentHelper.createElement("title");
//设置值
titleElement.setText("凤姐玉照");
//添加到newbook
newBook.add(titleElement);
//将新book元素添加到root元素
rootElement.add(newBook);
//将document保存
//持久化流
//创建输出文件的位置
FileOutputStream out = new FileOutputStream("books.dom4j.xml");
XMLWriter writer = new XMLWriter(out);
//添加内容对象
writer.write(document);
//关闭流
writer.close();
}
public static void delete(String[] args) throws Exception {
//获得document
//获得解析流
SAXReader reader = new SAXReader();
//解析xml
Document document = reader.read("books.xml");
//删除 b002
Node bookNode = document.selectSingleNode("//book[@id='b002']");
//获得父节点
Node parent = bookNode.getParent();
Element parentElement = (Element) parent;
//删除操作
parentElement.remove(bookNode);
//将document保存
//持久化流
//创建输出文件的位置
FileOutputStream out = new FileOutputStream("books.dom4j.xml");
XMLWriter writer = new XMLWriter(out);
//添加内容对象
writer.write(document);
//关闭流
writer.close();
}
public static void update(String[] args) throws Exception {
//获得document
//获得解析流
SAXReader reader = new SAXReader();
//解析xml
Document document = reader.read("books.xml");
//修改 b002 price 100
Node bookNode = document.selectSingleNode("//book[@id='b002']");
//强转转换
Element bookElement = (Element) bookNode;
//通过指定的名称获得相应的元素
Element priceElement = bookElement.element("price");
//修改值
// priceElement.getText();
priceElement.setText("100");
//将document保存
//持久化流
//创建输出文件的位置
FileOutputStream out = new FileOutputStream("books.dom4j.xml");
XMLWriter writer = new XMLWriter(out);
//添加内容对象
writer.write(document);
//关闭流
writer.close();
}
}