1 概念
xml:extended markup language :可扩展的标记语言
语法:标记类语言的语法:<标签名 属性名="属性值" 属性名="属性值">数据</标签名>
概念:xml html
相同之处:都是标记类语言:语法相同 作用都是通过标签封装数据
不同之处:
1: html的标签和属性是预定义的:
xml的标签和属性是自定义
2: 是否区分大小写
浏览器内置有对标记类语言解析的引擎
注意事项
* 纯文本语言:后缀名必须是.xml
* xml文件必须有两部分组成:声明区+数据区
* 数据区有且只有一个根标签:所有的其他标签都是此根标签的子标签
* 标签之前可以合理嵌套
* 属性写在起始标签中:属性格式:属性名=属性值
* 属性值可以写在单引号、双引号、不加引号:规范:双引号
* 标签名/属性名:命名规范:由数字 字母 _ 汉字等组成 但不能以数字开头
* 标签名/属性名区分大小写
* 通过字符实体来表示特殊字符
<?xml version='1.0' encoding='utf-8' ?> <!--声明区:设置当前xml的版本和编码集-->
<!--数据区:当前xml中的数据-->
<dangAn id="10001">
<班级 id="cla_1">
<student id="stu_11">
<sname>韩梅梅</sname>
<sex>女</sex>
<score>11.5</score>
<sdy>false</sdy>
</student>
<student id="stu_12">
<sname>韩庚</sname>
<sex>男</sex>
<score>21.5</score>
<sdy>true</sdy>
</student>
<student id="stu_13">
<sname>韩信</sname>
<sex>男</sex>
<score>41.5</score>
<sdy>false</sdy>
</student>
</班级>
<班级 id="cla_2">
<student id="stu_21">
<sname>张三</sname>
<sex>女</sex>
<score>12.5</score>
<sdy>false</sdy>
</student>
<student id="stu_22">
<sname>张三丰</sname>
<sex>男</sex>
<score>22.5</score>
<sdy>true</sdy>
</student>
<student id="stu_23">
<sname>张国荣</sname>
<sex>男</sex>
<score>42.5</score>
<sdy>false</sdy>
</student>
<student id="stu_23">
<sname>< a ></sname>
<sex>男</sex>
<score>52.5</score>
<sdy>false</sdy>
</student>
</班级>
</dangAn>
作用
作为软件的配置文件:配置信息:软件启动或者运行中需要加载的数据
封装有关系的数据
2 xml解析
https://blog.csdn.net/cui__shen/article/details/90813385
方法
dom:document object model 文档对象模型
原理:把xml文档和文档中的所有元素封装为对象 这些有关系的对象 写成dom树
w3c的规范
sax:smple api for xml
原理:以事件驱动的机制 对xml文档进行快速扫描
只支持快速读取 不支持对文档的增删改
对dom的封装,简化
dom和sax的不同
概念:
不同之处:
1 dom支持对xml的增删改查
sax只支持读取 不支持增删改
2 dom需要把文档和元素都封装为对象 非常消耗内存 不建议读取大文件
sax擅长读取大文件
3 dom解析
把xml文档和文档中的所有元素封装为对象 这些有关系的对象 写成dom树
相关的类型
包:org.w3c.dom
-- Node接口: 所有类型的根接口-- 节点(元素)
---- Element接口:所有的标签
---- Text接口: 所有的文本
---- Comment接口: 所有的注释
---- Attr接口: 所有的属性
---- Document接口: 文档本身
3.0 准备
public static void main(String[] args) {
//获取xml
File file=new File("src\\1.txt");
System.out.println(file.getAbsolutePath());
//获取xml
String path=Test01.class.getClassLoader().getResource("dangAn.xml").getPath();
System.out.println(path);
//获取document对象
Document doc=xml2Doc(path);
System.out.println(doc);
}
//由xml获取document对象
public static Document xml2Doc(String path){
try {
//获取文档解析器工厂对象
DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
//获取文档解析器对象
DocumentBuilder builder=factory.newDocumentBuilder();//实例工厂模式:
//通过解析器对象的parse 由xml获document对象
return builder.parse(new File(path));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//吧document对象刷新到xml中
public static void doc2Xml(String path,Document doc){
try {
//创建Transformer工厂对象
TransformerFactory factory=TransformerFactory.newInstance();
//创建Transformer对象
Transformer tf=factory.newTransformer();
//设置编码集合:默认utf-8
tf.setOutputProperty(OutputKeys.ENCODING, "GBK");
//调用taranform方法把doc的信息刷新到xml中
tf.transform(new DOMSource(doc), new StreamResult(new File(path)));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
3.1 查询
* Document的方法:
* NodeList getElementsByTagName(标签名);获取文档中指定的所有标签对应的集合
* Element的方法:
* NodeList getElementsByTagName(标签名);获取当前标签对象中指定的子标签对应的集合
* String getTextContent();获取文本内容
* NamedNodeMap getAttributes();获取所有的属性
* Node的方法:
* String getNodeName(); 获取元素名字
* int getNodeType() ; 获取元素的类型:Document是9 Comment是8 Element是1 Attr是2 Text是3
* NodeList getChildNodes(); 获取所有的子元素::标签+文本
* Boolean hasChildNodes(); 判断是否有子元素
* Attr的方法
* String getName();获取属性名
* String getValue();获取属性值
* NamedNodeMap和 NodeList的方法
* int getLength()
* Node item(int index)
//遍历整个xml文件
public static void showDoc(Node node){
System.out.println("元素:"+node.getNodeName()+":"+node.getNodeType());
//判断类型
if(node instanceof Document){
System.out.println("当前元素是:文档");
//获取其所有的子标签
NodeList zis=node.getChildNodes();
if(zis!=null){
for (int i = 0; i < zis.getLength(); i++) {
Node zi=zis.item(i);
showDoc(zi);
}
}
}else if(node instanceof Element){
Element ele=(Element)node;
System.out.println("当前元素是:标签");
//获取属性
NamedNodeMap attrs= ele.getAttributes();
if(attrs!=null){
for (int i = 0; i < attrs.getLength(); i++) {
showDoc(attrs.item(i));
}
}
//判断是否有子标签
if(ele.hasChildNodes()){
NodeList zis=ele.getChildNodes();
for (int i = 0; i < zis.getLength(); i++) {
showDoc(zis.item(i));
}
}else{
//获取文本内容
System.out.println("当前标签的文本内容:"+ele.getTextContent());
}
}else if(node instanceof Attr){
Attr attr=(Attr) node;
System.out.println("属性:"+attr.getName()+"="+attr.getValue());
}else if(node instanceof Comment ){
Comment com=(Comment)node;
System.out.println("注释:"+com.getNodeValue());
}
}
3.2 修改
* Element的方法:
* String getAttribute(String); 获取属性值
* void setAttribute(String,String); 添加/修改属性值
* void removeAttribute(String); 删除属性
*
* String getTextContent();获取文本内容
* void setTextContent(String);设置文本内容
*
* Node getParentNode();获取父标签
public static void update2(String path){
Document doc=xml2Doc(path);
//吧班级为id=cla_2的名字为张三丰的学生的性别更改为妖
//获取所有的班级标签
NodeList list=doc.getElementsByTagName("班级");
for (int i = 0; i < list.getLength(); i++) {
Element eleBanJi=(Element)list.item(i);
//获取其id属性
String id=eleBanJi.getAttribute("id");
if(id.equals("cla_2")){
System.out.println("1111");
//获取其中所有的sname标签
NodeList snameList=eleBanJi.getElementsByTagName("sname");
for (int j = 0; j < snameList.getLength(); j++) {
//获取cla_2下的一个sname标签
Element eleSname=(Element)snameList.item(j);
//获取其文本内容
String sname=eleSname.getTextContent().trim();
if(sname.equals("张三丰")){
//获取当前sname标签的父标签student标签
Element eleStu=(Element)eleSname.getParentNode();
//获取此父亲标签的sex子标签
Element eleSex=(Element)eleStu.getElementsByTagName("sex").item(0);
//修改完毕内容
eleSex.setTextContent("仙");
//添加学生标签的属性值
eleStu.setAttribute("title", "t9999");
//更改学生标签的属性
eleStu.setAttribute("id", "s_00001");
break;
}
}
break;
}
}
//吧更改后的document对象的信息刷新到xml中
doc2Xml(path,doc);
}
3.3 添加
* Document的方法:
* Node createElement(String);创建一个标签
* Element的方法:
* Node appendChild(node); 在当前标签下添加一个子标签 返回值是子标签
public static void add(Student s,String path){
//把参数student对象的信息添加到第一个班级标签下
Document doc=xml2Doc(path);
//获取第一个班级标签
Element eleBJ=(Element)doc.getElementsByTagName("班级").item(0);
//创建student标签
Element eleStu=(Element)doc.createElement("student");
//添加id属性
eleStu.setAttribute("id", s.getId());
//创建子标签
Element eleSname=(Element)doc.createElement("sname");
Element eleSex=(Element)doc.createElement("sex");
Element eleScore=(Element)doc.createElement("score");
Element eleSdy=(Element)doc.createElement("sdy");
//设置文本内容
eleSname.setTextContent(s.getSname());
eleSex.setTextContent(s.getSex()+"");
eleScore.setTextContent(s.getScore()+"");
eleSdy.setTextContent(s.getSdy()+"");
//把子标签添加到父标签下
eleStu.appendChild(eleSname);
eleStu.appendChild(eleSex);
eleStu.appendChild(eleScore);
eleStu.appendChild(eleSdy);
System.out.println(eleBJ.appendChild(eleStu).getNodeName());
//吧更改后的document对象的信息刷新到xml中
doc2Xml(path,doc);
}
3.4 删除
* Element的方法:
* void removeChild(node);删除当前标签的参数子标签
* void removeAttribute(String); 删除属性
public static void delete(String path){
//把参数student对象的信息添加到第一个班级标签下
Document doc=xml2Doc(path);
//删除第一个student标签的title属性
Element eleStu=(Element)doc.getElementsByTagName("student").item(0);
eleStu.removeAttribute("title");
//删除第二个student标签
Element eleStu2=(Element)doc.getElementsByTagName("student").item(1);
eleStu2.getParentNode().removeChild(eleStu2);//通过父标签 删除子标签
//吧更改后的document对象的信息刷新到xml中
doc2Xml(path,doc);
}
4 xml练习
public class Teacher {
// tid tname tsex tsalary tbirthday
private int tid;
private String tname;
private String tsex;
private float tsalary;
private Date tbirthday;
...
}
package com.zhiyou100.demo02.xml;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
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.NodeList;
public class LianXi {
private static File file;
static{
file=new File("src/Teacher.xml");
init();
}
private static void init(){
if(!file.exists()){
try {
file.createNewFile();
//添加声明区和根标签 dangAn
BufferedWriter bout=new BufferedWriter(new FileWriter(file));
bout.write("<?xml version=\"1.0\" encoding=\"gbk\" standalone=\"no\"?>");
bout.newLine();
bout.write("<dangAn>");
bout.newLine();
bout.write("</dangAn>");
bout.flush();
bout.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
//添加
// addOne(new Teacher(1002, "张三丰", "男", 3050, new Date(0)));
// addOne(new Teacher(1003, "张无忌", "男", 3100, new Date(0)));
// addOne(new Teacher(1004, "张翠山", "男", 3200, new Date(0)));
// addOne(new Teacher(1005, "张思", "女", 3030, new Date(0)));
// addOne(new Teacher(1006, "刘思思", "女", 3400, new Date(0)));
//System.out.println(deleteOne(1001));
//System.out.println(deleteOne(1001));
//updateOne(new Teacher(1006, "刘sisi", "妖", 3333, new Date(0)));
List<Teacher> list=getAll();
for (Teacher teacher : list) {
System.out.println(teacher);
}
}
//添加一个:把一个老师对象的信息添加到xml中 对应一个teacher标签
// void addOne(Teacher t);
public static void addOne(Teacher t){
//int tid, String tname, String tsex, float tsalary, Date tbirthday
Document doc=xml2Doc(file);
//获取dangAn标签
Element root=(Element)doc.getElementsByTagName("dangAn").item(0);
//创建teacher标签
Element eleTea=doc.createElement("Teacher");
//添加属性
eleTea.setAttribute("tid", t.getTid()+"");
//创建子标签
Element eleTname=doc.createElement("tname");
eleTname.setTextContent(t.getTname());
Element eleTsex=doc.createElement("tsex");
eleTsex.setTextContent(t.getTsex());
Element eleTsalary=doc.createElement("tsalary");
eleTsalary.setTextContent(t.getTsalary()+"");
Element eleTbirthday=doc.createElement("tbirthday");
eleTbirthday.setTextContent(t.getTbirthday().toLocaleString());
//把子标签添加到父标签上
root.appendChild(eleTea);
eleTea.appendChild(eleTname);
eleTea.appendChild(eleTsex);
eleTea.appendChild(eleTsalary);
eleTea.appendChild(eleTbirthday);
//把doc刷新到xml中
doc2Xml(file, doc);
}
//删除一个:根据
// int deleteOne(int tid);
public static int deleteOne(int id){
//int tid, String tname, String tsex, float tsalary, Date tbirthday
Document doc=xml2Doc(file);
//获取dangAn标签
NodeList teaList=doc.getElementsByTagName("Teacher");
boolean b=false;
for (int i = 0; i < teaList.getLength(); i++) {
Element eleTea=(Element)teaList.item(i);
//获取其tid属性
int tid=Integer.parseInt(eleTea.getAttribute("tid"));
if(tid==id){
eleTea.getParentNode().removeChild(eleTea);
b=true;
break;
}
}
//把doc刷新到xml中
doc2Xml(file, doc);
return b?1:0;
}
//修改一个
// int updateOne(Teacher t);
public static int updateOne(Teacher t){
//int tid, String tname, String tsex, float tsalary, Date tbirthday
Document doc=xml2Doc(file);
//获取dangAn标签
NodeList teaList=doc.getElementsByTagName("Teacher");
boolean b=false;
for (int i = 0; i < teaList.getLength(); i++) {
Element eleTea=(Element)teaList.item(i);
//获取其tid属性
int tid=Integer.parseInt(eleTea.getAttribute("tid"));
if(tid==t.getTid()){
//更改子标签的文本内容
eleTea.getElementsByTagName("tname").item(0).setTextContent(t.getTname());
eleTea.getElementsByTagName("tsex").item(0).setTextContent(t.getTsex());
eleTea.getElementsByTagName("tsalary").item(0).setTextContent(t.getTsalary()+"");
eleTea.getElementsByTagName("tbirthday").item(0).setTextContent(t.getTbirthday().toLocaleString());
b=true;
break;
}
}
//把doc刷新到xml中
doc2Xml(file, doc);
return b?1:0;
}
//获取所有
// List<Teacher> getAll();
public static List<Teacher> getAll(){
//int tid, String tname, String tsex, float tsalary, Date tbirthday
Document doc=xml2Doc(file);
//获取dangAn标签
NodeList teaList=doc.getElementsByTagName("Teacher");
List<Teacher> list=new ArrayList<Teacher>();
for (int i = 0; i < teaList.getLength(); i++) {
Element eleTea=(Element)teaList.item(i);
Teacher t=new Teacher();
t.setTid(Integer.parseInt(eleTea.getAttribute("tid")));
t.setTname(eleTea.getElementsByTagName("tname").item(0).getTextContent());
t.setTsex(eleTea.getElementsByTagName("tsex").item(0).getTextContent());
t.setTsalary(Float.parseFloat(eleTea.getElementsByTagName("tsalary").item(0).getTextContent()));
String tbirthdayStr=eleTea.getElementsByTagName("tbirthday").item(0).getTextContent();
try {
//1970-1-1 8:00:00
t.setTbirthday(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(tbirthdayStr));
} catch (Exception e) {
throw new RuntimeException(e);
}
list.add(t);
}
return list;
}
// 由xml获取document对象
public static Document xml2Doc(File file) {
try {
// 获取文档解析器工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
// 获取文档解析器对象
DocumentBuilder builder = factory.newDocumentBuilder();// 实例工厂模式:
// 通过解析器对象的parse 由xml获document对象
return builder.parse(file);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
// 吧document对象刷新到xml中
public static void doc2Xml(File file, Document doc) {
try {
// 创建Transformer工厂对象
TransformerFactory factory = TransformerFactory.newInstance();
// 创建Transformer对象
Transformer tf = factory.newTransformer();
// 设置编码集合:默认utf-8
tf.setOutputProperty(OutputKeys.ENCODING, "GBK");
// 调用taranform方法把doc的信息刷新到xml中
tf.transform(new DOMSource(doc), new StreamResult(file));
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}