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.javapackage 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();



 }}