1、XML技术除用于保存有关系的数据之外,它还经常用作软件配置文件,
以描述程序模块之间的关系。
2、一个XML文件分为以下几部分内容:
文档声明
元素
属性
注释
CDATA区、特殊字符
处理指令
3、在编写XML文档时,需要先使用文档声明,声明XML文档的类型:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
standalone属性说明文档是否独立,如果是no则该文档不能独立打开,必须依赖于其他文档(注:IE没有关注这个属性,所以能打开)
4、对于XML标签(元素)中出现的所有空格和换行,XML解析程序都会当作标签内容进行处理
例如下面两段内容的意义是不一样的。
第一段:
<网址>www.fdjask.cn</网址>
第二段:
<网址>
www.fdjask.cn
</网址>
5、在编写XML文件时,有些内容可能不想让解析引擎解析执行,而是当作原始内容处理
遇到此情况,可以把这些内容放在CDATA区里,对于CDATA区域内的内容,XML解析程序
不会处理,而是直接原封不动的输出。
语法:
<![CDATA[内容]]>
例:
<![CDATA[
<itcast>
<br/>
</itcast>
]]>
6、转义字符,若想显示其原始样式,也可以使用转义的形式予以处理
7、处理指令用来指挥解析引擎如何解析XML文档内容,在XML文档中可以使用xml-stylesheet指令
通知XML解析引擎,应用css文件显示XML文档内容
例:<?xml-stylesheet type="text/css" href="1.css">
8、在XML技术里,可以编写一个文档来约束一个XML文档的书写规范,这称之为XML约束
常用的约束技术:XML DAD;XML Schema
9、DOM和SAX解析方式的优缺点:
1、DOM解析的优点是对文档增删改查比较方便,缺点是占用内存比较大
2、SAX解析的优点是占用内存少,解析速度快,缺点是只适合做文档的读取,不适合做文档的增删改查
10、调整JVM大小:JVM默认是64M内存,-Xmx80m就被配置成80M内存
2、使用Jaxp对xml文档进行dom解析
获取DOM
package cn.itcast.xml.eclipse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
public class AnalysisXml {
public static void main(String[]args) throws Exception{
//1、创建工厂
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
//2、得到dom解析器
DocumentBuilder builder=factory.newDocumentBuilder();
//3、解析xml文档,得到代表文档的document
Document document=builder.parse("book.xml");
}
}
对xml文档进行增删改查
package cn.itcast.xml.eclipse;
//使用dom方式对xml文档进行增删改查(crud)
import java.io.FileOutputStream;
import java.io.IOException;
import javax.xml.crypto.dsig.Transform;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.junit.Test;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class AnalysisCrud {
@Test
public void read() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//读取book.xml中的 JavaScript网页开发
NodeList list=document.getElementsByTagName("书名");
Node node=list.item(1);
String content=node.getTextContent();
System.out.println(content);
}
//得到xml文档中的所有标签
@Test
public void read2() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//读取book.xml中的 JavaScript网页开发
//NodeList list=document.getElementsByTagName("书架");
Node root=document.getElementsByTagName("书架").item(0);
list(root);
}
public void list(Node node) {
if(node instanceof Element) {
System.out.println(node.getNodeName());
}
NodeList list=node.getChildNodes();
for(int i=0;i<list.getLength();i++) {
Node child=list.item(i);
list(child);
}
}
//得到xml文档中标签属性的值:<书名 name="xxx">JavaWeb</书名>
@Test
public void read3() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//读取book.xml中的 JavaScript网页开发
Element bookname=(Element)document.getElementsByTagName("书名").item(0);
String value=bookname.getAttribute("name");
System.out.println(value);
}
//节点的增删改查
@Test
//增加节点
public void add() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//创建节点
Element price=document.createElement("售价");
price.setTextContent("59元");
//把创建的节点挂到第一本书上
Element book=(Element)document.getElementsByTagName("书").item(0);
book.appendChild(price);
//把更新后内存写回到xml文档
TransformerFactory tffactory=TransformerFactory.newInstance();
Transformer tf=tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
@Test
//在指定位置插入节点
public void add1() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//创建节点
Element price=document.createElement("售价");
price.setTextContent("59元");
//得到参考节点
Element refNode=(Element)document.getElementsByTagName("售价").item(0);
//得到要挂载的节点
Element book=(Element)document.getElementsByTagName("书").item(0);
//往book节点指定位置插入
book.insertBefore(price, refNode);
//把更新后内存写回到xml文档
TransformerFactory tffactory=TransformerFactory.newInstance();
Transformer tf=tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
@Test
//向xml文档节点添加属性,<书名>JavaWeb</书名>上添加Nname="新添加的属性"属性
public void addAttribute() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//找到需要添加节点的属性
Element bookname=(Element)document.getElementsByTagName("书名").item(0);
//添加属性
bookname.setAttribute("Nname","新添加的属性");
//把更新后内存写回到xml文档
TransformerFactory tffactory=TransformerFactory.newInstance();
Transformer tf=tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
//删除节点
@Test
//向xml文档节点添加属性,<书名>JavaWeb</书名>上添加Nname="新添加的属性"属性
public void delNode() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
/*第一种方法:
* //找到要删除的节点
Element e=(Element)document.getElementsByTagName("售价").item(0);
//得到要删除的节点的父节点
Element book=(Element)document.getElementsByTagName("书").item(0);
//父节点删除子节点
book.removeChild(e);*/
//第二种方法:
//找到要删除的节点
Element e=(Element)document.getElementsByTagName("售价").item(0);
//通过此节点找到它的父节点,然后通过父节点删除它自身
e.getParentNode().removeChild(e);
//把更新后内存写回到xml文档
TransformerFactory tffactory=TransformerFactory.newInstance();
Transformer tf=tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
@Test
//更新节点
public void UpdateNode() throws Exception {
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=factory.newDocumentBuilder();
Document document=builder.parse("src/book.xml");
//找到需要添加节点的属性
Element bookname=(Element)document.getElementsByTagName("售价").item(0);
//添加属性
bookname.setTextContent("119元");
//把更新后内存写回到xml文档
TransformerFactory tffactory=TransformerFactory.newInstance();
Transformer tf=tffactory.newTransformer();
tf.transform(new DOMSource(document), new StreamResult(new FileOutputStream("src/book.xml")));
}
}
3、sax解析
book.xml
<?xml version="1.0" encoding="utf-8"?>
<书架>
<书>
<书名 Nname="新添加的属性" name="xxx">JavaWeb</书名>
<作者>张孝祥</作者>
<售价>119元</售价>
<售价>209元</售价>
</书>
<书>
<书名>JavaScript网页开发</书名>
<作者>黎明</作者>
<售价>28元</售价>
</书>
</书架>
package cn.itcast.sax;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
public class saxDemo1 {
/*
* sax解析xml文档
* */
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// TODO Auto-generated method stub
//1、创建解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2、得到解析器
SAXParser sp=factory.newSAXParser();
//3、得到读取器
XMLReader reader=sp.getXMLReader();
//4、设置内容处理器
reader.setContentHandler(new ListHandler());
//5、读取xml文档内容
reader.parse("src/book.xml");
}
}
class ListHandler implements ContentHandler{
@Override
public void setDocumentLocator(Locator locator) {
// TODO Auto-generated method stub
}
@Override
public void startDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endDocument() throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startPrefixMapping(String prefix, String uri) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void endPrefixMapping(String prefix) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void startElement(String uri, String localName, String name, Attributes atts) throws SAXException {
System.out.println("<"+name+">");
for(int i=0;atts!=null&&i<atts.getLength();i++) {
String attName=atts.getQName(i);
String attValue=atts.getValue(i);
System.out.println(attName+"="+attValue);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
System.out.println(qName);
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
System.out.println(new String(ch,start,length));
}
@Override
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void processingInstruction(String target, String data) throws SAXException {
// TODO Auto-generated method stub
}
@Override
public void skippedEntity(String name) throws SAXException {
// TODO Auto-generated method stub
}
}
package cn.itcast.sax;
import java.io.IOException;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class saxDemo2 {
/*
* sax解析xml文档
* */
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// TODO Auto-generated method stub
//1、创建解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2、得到解析器
SAXParser sp=factory.newSAXParser();
//3、得到读取器
XMLReader reader=sp.getXMLReader();
//4、设置内容处理器
reader.setContentHandler(new TagValueHandler());
//5、读取xml文档内容
reader.parse("src/book.xml");
}
}
class TagValueHandler extends DefaultHandler{
private String currentTag;//记住当前解析到的是什么标签
private int needNumber=2;//记住想获取第几个作者标签的值
private int currentNumber;//当前解析到的是第几个
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentTag=qName;
if(currentTag.equals("作者")) {
currentNumber++;
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
currentTag=null;
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("作者".equals(currentTag)&¤tNumber==needNumber) {
System.out.println(new String(ch,start,length));
}
}
}
book.java
package cn.itcast.sax;
public class Book {
private String name;
private String author;
private String 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 String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
}
package cn.itcast.sax;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.ContentHandler;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
public class saxDemo3 {
/*
* sax解析xml文档
* */
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
// TODO Auto-generated method stub
//1、创建解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2、得到解析器
SAXParser sp=factory.newSAXParser();
//3、得到读取器
XMLReader reader=sp.getXMLReader();
//4、设置内容处理器
BeanListHandler handle=new BeanListHandler();
reader.setContentHandler(handle);
//5、读取xml文档内容
reader.parse("src/book.xml");
List list=handle.getBooks();
System.out.println(list);
}
}
//把xml文档中的每一本书封装到一个book对象,并把多个book对象放在一个list集合中返回
class BeanListHandler extends DefaultHandler{
private List list=new ArrayList();
private String currentTag;
private Book book;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
currentTag=qName;
if("书".equals(currentTag)) {
book=new Book();
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("书名".equals(currentTag)) {
String name=new String(ch,start,length);
book.setName(name);
}
if("作者".equals(currentTag)) {
String author=new String(ch,start,length);
book.setName(author);
}
if("售价".equals(currentTag)) {
String price=new String(ch,start,length);
book.setName(price);
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if(qName.equals("书")) {
list.add(book);
book=null;
}
currentTag=null;
}
public List getBooks() {
return list;
}
}
4、dom4j解析xml文档(推荐使用这种,高效)
package cn.itcast.dom4j;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
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 org.junit.Test;
public class demo1 {
//读取xml文档第二本书的:<书名>JavaScript网页开发</书名>
@Test
public void read() throws Exception {
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/book.xml"));
//获取书名
Element root=document.getRootElement();
Element book=(Element)root.elements("书").get(1);
String value=book.element("书名").getText();
System.out.println(value);
//获取书的属性 name="xxx"值
Element book1=(Element)root.elements("书").get(0);
String name=book1.element("书名").attributeValue("name");
System.out.println(name);
}
//在第一本书上添加一个新的售价:<售价>209元<售价>
@Test
public void add() throws DocumentException, IOException {
//给在第一本书上创建一个新的售价
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/book.xml"));
Element book=document.getRootElement().element("书");
book.addElement("售价").setText("209元");
//将更新后的写入xml文档
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");//设置document写的格式,默认是改变gb312
/*
* FileOutputStream以字节流的格式写入时会查找编码表,即format,当设置为utf-8时写入的也是
* utf-8格式的,所以当我们的xml文档的编码也是utf-8则不会乱码,保证一个规则:设置的编码与xml
* 编码一致即可,推荐使用字节流写入
* */
XMLWriter writer=new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
/*
* 而使用FileWriter字符流的格式写入的时候document不会查找编码表,即以gb2312的格式写入
* 我们的xml文档是utf-8格式的,则会导致乱码问题
XMLWriter writer=new XMLWriter(new FileWriter("src/book.xml"));
writer.write(document);
writer.close();
*/
}
//在指定位置上添加一个新的售价:<售价>209元</售价> 更改保存了list集合的顺序
@Test
public void add2() throws DocumentException, IOException {
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/book.xml"));
Element book=document.getRootElement().element("书");
List list=book.elements();//获取到书的所有子节点
Element price=DocumentHelper.createElement("售价");
price.setText("309元");
list.add(2, price);
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}
//删除上面添加的售价节点
@Test
public void delete() throws DocumentException, IOException {
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/book.xml"));
Element price=document.getRootElement().element("书").element("售价");
price.getParent().remove(price);
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}
//修改节点
@Test
public void update() throws DocumentException, IOException {
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/book.xml"));
Element book=(Element)document.getRootElement().elements("书").get(1);
book.element("作者").setText("黎明");
OutputFormat format=OutputFormat.createPrettyPrint();
format.setEncoding("utf-8");
XMLWriter writer=new XMLWriter(new FileOutputStream("src/book.xml"),format);
writer.write(document);
writer.close();
}
}
采用Xpath包可以快速定位到某个节点,而不需要一个一个的去遍历
package cn.itcast.dom4j;
import java.io.File;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class Xpathdemo2 {
public static void main(String[] args) throws DocumentException {
String username="aaa";
String password="1223";
//检测xml文档是否有匹配的用户名和密码
SAXReader reader=new SAXReader();
Document document=reader.read(new File("src/users.xml"));
//在字符串中传入变量的方法:"+username+",将该字符串转成了变量(即保持变量的特性)
Node node=document.selectSingleNode("//user[@username='"+username+"' and @password='"+password+"']");
if(node==null) {
System.out.println("用户名或密码错误!!");
}else {
System.out.println("登陆成功");
}
}
}
5、Schema文档格式