package a01JavaWebXML;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;
/*
* iso8859-1(latin1)-1字节1字符
* GBK-GBK2312------ 2字节1字符包含中文
* unicode-----------3字节1字符
* UTF-8 UTF-16 ----3字节一个中文 生僻字4字节
*/
/*
*
* SAX解析
* Java官方提供的解析
* pull解析
*
*
* SAX解析流程
* <root> ->startDocument
* <first> ->startElement qName=first
* 1 ->characters 1
* <first> ->endElement qName=first
*</root> ->endDocument
*
*
*/
public class JavaWebXMLSax {
public static void main(String[] args) throws Exception{
//1.使用SAXParserFactory创建SAX解析工厂
SAXParserFactory factory=SAXParserFactory.newInstance();
//2.通过SAX解析工厂得到解析器对象
SAXParser paser=factory.newSAXParser();
//3.通过解析器对象得到一个XML的读取器
XMLReader reader=paser.getXMLReader();
//4.设置读取器的事件处理器
reader.setContentHandler(new MyHandler2());
//5.解析xml文件
reader.parse("E:\\ChenXunCode\\TarenaBigData\\JavaWeb\\book.xml");
}
}
//获取第二本书的书名的名字
//自己定义的事件处理器
class MyHandler2 extends DefaultHandler{
private String eleName = null;
private int count = 0;
//开始解析节点 startElement() 开始标签qName
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
eleName = qName; //节点刚开始,eleName记录开始节点,且count++
if("书名".equals(eleName)){
count++;
}
}
//保存节点内容 characters() 标签体new String(ch,start,length)
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if("书名".equals(eleName) && count == 2){ //如果是第二个书签,且书签名为书名,就打印第二本书的书名的名字
String str = new String(ch,start,length);
System.out.println(str);
}
}
//结束解析节点 endElement() 结束标签qName
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
if("书名".equals(qName)){ //节点结束,eleName为空
//-------------------注意听一下--------------------------------------------
eleName = null;
}
}
}
class MyHandle1 extends DefaultHandler{
// 开始解析文档 startDocument()
@Override
public void startDocument() throws SAXException {
System.out.println("文档解析开始了。。。");
}
//开始解析节点 startElement() 开始标签qName
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
System.out.println("发现了元素的开始标签"+qName);
}
//保存节点内容 characters() 标签体new String(ch,start,length)
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
System.out.println("发现了标签体"+new String(ch,start,length));
}
//结束解析节点 endElement() 结束标签qName
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
System.out.println("发现了元素的结束标签"+qName);
}
//文档解析结束 endDocument()
@Override
public void endDocument() throws SAXException {
System.out.println("文档解析结束了。。");
}
}
package a01JavaWebXML;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/*
*
* Dom解析
* Java官方提供的解析
* Dom4j解析
* 还有一种
*
*/
//思想:1.先获取根节点root getRootElement()
// 2.根节点下的所有"书"节点的第二个boo2file root.elements("书").get(1)
// 3.这个第二个"书"节点下的"书名"子节点bookNameFile book2file.element("书名")
// 4.获取"书名"子节点里面的内容bookName bookNameFile.getText()
//获取第二本书的书名的名字
public class JavaWebXMLDom {
public static void main(String[] args) throws Exception {
//1.创建解析器 SAXReader
SAXReader reader = new SAXReader();
//2.利用解析器读取xml文件 SAXReader.read(文件)
Document dom = reader.read("book.xml");
//3.获取根节点 Document.getRootElement()
Element root = dom.getRootElement();
//4.获取<书架>下的第二个节点
Element book2file=(Element) root.elements("书").get(1);
//上面这一步等价于下面两步
//获取root下所有节点集合 List<Element> list = root.elements("书");
//获取第二个元素 Element bookEle2 = list.get(1);
Element bookNameFile=book2file.element("书名");
String bookName=bookNameFile.getText();
System.out.println(bookName);
}
}
package a01JavaWebXML;
import java.io.FileOutputStream;
import org.dom4j.Attribute;
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;
/*
* Dom解析
* <?xml version="1.0" encoding="utf-8" ?>
* <root>
* <head>
* <title>example<title>
* </head>
* <body>
* <p>cont1</p>
* <p>cont2</p>
* </body>
* <foot>
* <author name="wuyun"/>
* </foot>
*
* </root>
*
*
*
*
* 基于DOM的XML解析器将一个XML文档转换成一个对象模型的集合(通常称DOM树),
* 应用程序通过对这个对象模型的操作,来实现对XML文档数据的操作。
* Document:dom
*
* Element:root
*
* Element:head Element:body Element:foot
* | | | |
* Element:title Element:p Element:p Element:author
* | | |
* Character:example Character:cont1 Character:cont2 Attr:name
*
*
*
*
* dom
* 书架
* 书 书
* 书名 作者 售价 书名 作者 售价
*/
public class JavaWebXMLDom02Operator {
//1.获取某个节点的值
//输出55.00元
@Test
public void getEle() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement(); //获取根节点
//2.通过根节点获取需要的元素
Element bookEle = (Element) root.elements("书").get(1);//获取<书架>下的第二个节点<书>
//上面这一步等价于下面两步
//获取root下所有节点集合 List<Element> list = root.elements("书");
//获取第二个元素 Element bookEle2 = list.get(1);
Element priceEle = bookEle.element("售价"); //获取<书>节点下的<售价>节点
String str = priceEle.getText();
System.out.println(str);
}
//2.增加一个子节点 createElement()
// DocumentHelper.createElement(节点名) Elements.setText() Elements.add(Elements)
@Test
public void addEle() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//--------------------start增加一个子节点--------------------
//2.凭空创建<特价>节点并且设置标签体为 0.5元
Element price2Ele = DocumentHelper.createElement("特价"); //创建Document对象 DocumentHelper.createElement()
price2Ele.setText("0.5元");
//3.获取第二个<书>节点
Element book2Ele = (Element) root.elements("书").get(1);
//4.将<特价>挂载到<书>节点上
book2Ele.add(price2Ele);
//---------------------end增加一个子节点--------------------
//注意:以上修改只是在内存中修改dom信息,不写回文件的,文件中的信息不会修改
//5.第一种方式:将内存中的dom信息写回文件
//OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream("book.xml"), "utf-8");
//dom.write(writer);
//writer.flush();
//writer.close();
//5.第二种方式:将内存中的dom信息写回文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),format);
writer.write(dom);
writer.flush();
writer.close();
}
//3.删除一个子节点
@Test
public void removeEle() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//--------------------start删除一个子节点--------------------
// Element.getParent().remove(Element)
//2.获取第二个<作者>节点
Element authorEle= ((Element) root.elements("书").get(1)).element("作者");
//3.从<作者>节点的父节点中移除<作者>节点
authorEle.getParent().remove(authorEle);
//--------------------end删除一个子节点--------------------
//注意:以上修改只是在内存中修改dom信息,不写回文件的,文件中的信息不会修改
//4.将内存中的dom输出到文件中
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//4.增加一个属性 createAttribute()
// DocumentHelper.createAttribute(节点, 属性, 属性值); Elements.add(attr)
@Test
public void addAttr() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//-------------------start增加一个属性----------------------
//2.获取第二个<书>节点
Element book2Ele = (Element) root.elements("书").get(1);
//3.凭空创建属性 出版社="达内出版社"
Attribute attr = DocumentHelper.createAttribute(book2Ele, "出版社", "达内出版社");
//4.将属性挂载到节点上
book2Ele.add(attr);
//-------------------end增加一个属性----------------------
//5.写出dom到文件
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//5.获取一个属性
// Elements.attribute(属性名) Attribute.getName() Attribute.getValue()
@Test
public void getAttr() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.获取第二个<书>节点
Element book2Ele = (Element) root.elements("书").get(1);
//-------------------start获取一个属性-----------------
//3.获取<书>上的属性
Attribute attr = book2Ele.attribute("出版社");
String name = attr.getName();
String value = attr.getValue();
System.out.println(name+"~"+value);
//------------------end获取一个属性-----------------------------------
}
//6.删除一个属性
//Element.attribute(属性名) Element.remove(attr)
@Test
public void removeAttr() throws Exception{
//1.获取解析器 解析xml获取dom 通过dom获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.获取第二个<书>节点
Element book2Ele = (Element) root.elements("书").get(1);
//----------start删除一个属性--------------------------------
//3.获取<书>上的属性
Attribute attr = book2Ele.attribute("出版社");
//4.从<书>节点上移除指定属性
book2Ele.remove(attr);
//----------end删除一个属性---------------------------------
//5.将内存中的dom写出到文件中
//注意:如果不写这步,仅在内存中操作整个xml文件,实际xml未变
XMLWriter writer = new XMLWriter(new FileOutputStream("book.xml"),OutputFormat.createPrettyPrint());
writer.write(dom);
writer.flush();
writer.close();
}
//----------------创建xml文件createDocument()-------------------------------------
@Test
public void createDom() throws Exception{
//1.直接内存中构建一个Dom DocumentHelper.createDocument()
Document dom = DocumentHelper.createDocument();
//2.创建各个节点元素 DocumentHelper.createElement(节点名)
Element ChinaEle = DocumentHelper.createElement("中国");
Element bjEle = DocumentHelper.createElement("北京");
Element shEle = DocumentHelper.createElement("上海");
Element gzEle = DocumentHelper.createElement("广州");
Element hdEle = DocumentHelper.createElement("海淀");
hdEle.setText("配电脑");
Element pgEle = DocumentHelper.createElement("平谷");
pgEle.setText("桃");
//3.挂在节点上
dom.add(ChinaEle); //Document.add() 根节点<中国>
ChinaEle.add(bjEle); //<中国>节点下有<北京><上海><广州>
ChinaEle.add(shEle);
ChinaEle.add(gzEle);
bjEle.add(hdEle); //<北京>节点下有<海淀><平谷>
bjEle.add(pgEle);
//4.输出到文件
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileOutputStream("country.xml"),format);
writer.write(dom);
writer.flush();
writer.close();
}
/*
*
上面输出counrty.xml文件,里面内容为
<?xml version="1.0" encoding="UTF-8"?>
<中国>
<北京>
<海淀>配电脑</海淀>
<平谷>桃</平谷>
</北京>
<上海/>
<广州/>
</中国>
*/
}
package a01JavaWebXML;
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;
/*
* dom4j -XPath
*
*1.从根路径开始的绝对路径方式获取/AAA
例子:获取所有AAA下的BBB下的所有CCC:/AAA/BBB/CCC
2.所有指定名称的元素//AAA
例子:获取所有名称为AAA的元素
3.使用*号匹配符获得所有满足条件的元素
例子:获取AAA下BBB下所有的元素:/AAA/BBB/*
4.使用中括号,获取多个匹配元素中的某一个,可以使用last()函数获取最后一个
例子:获取AAA下所有BBB的第二个:/AAA/BBB[2]
例子:获取AAA下所有BBB的最后一个:/AAA/BBB[last()]
5.指定某一属性:@AttName,可以配合中括号使用
例子:获取所有id属性://@id
例子:获取所有具有id属性的BBB元素://BBB[@id]
例子:获取所有不具有属性的BBB元素://BBB[not(@*)]
例子:获取属性的值为某一个固定值的BBB元素://BBB[@id='b1']
*
*
*/
public class JavaWebXMLDom03XPath {
public static void main(String[] args) throws Exception {
//1.创建解析器 解析xml获取dom 获取根节点
SAXReader reader = new SAXReader();
Document dom = reader.read("book.xml");
Element root = dom.getRootElement();
//2.通过xpath获取需要的元素
//注意:Element.selectSingleNode(xpathQuery) 选择匹配 XPath 表达式的第一个
//xpath下的[num] 例如书[2]就是第二个书节点,不是第三个书节点
Element book2Ele = (Element) root.selectSingleNode("//书[2]/书名"); //获取第一个满足 第二个"书"节点下的"书名"节点
System.out.println(book2Ele.getText());
//3.通过xpath获取属性
//注意:Element.selectNodes(xpathQuery) 选择匹配 XPath 表达式的结点集合
List<Attribute> list = root.selectNodes("//@出版社"); //获取所有"出版社"属性
for(Attribute attr : list){
System.out.println(attr.getValue());
}
}
}