一.xml介绍
XML(EXtensible Markup Language),可扩展标记语言 类似HTML
XML的被设计为用来传输数据,而非显示数据
XML被设计具有自我描述性
XML 没有被预定义 需要自己定义标签
XML 不是HTML的替代
XML 和 HTML 是为了不同的目的设计的
XML 被设计为存储和传输 数据
HTML 被设计用来显示数据
HTML 宗旨 在于显示信息
XML 宗旨 在于传输数据
XML与操作系统、编程语言的开发平台无关
可以实现不同系统之间的数据交换
XML作用:
数据交互
配置应用程序和网站
Ajax基石
xml例子:
<?xml version="1.0" encoding="UTF-8"?>
<!--上面是版本信息和字符编码-->
<books>
<book id="bk101">
<author>王珊</author>
<title>.NET高级编程</title>
<description>包含C#框架和网络编程等</description>
</book>
<book id="bk102">
<author>李明明</author>
<title>XML基础编程</title>
<description>包含XML基础概念和基本作用</description>
</book>
</books>
二.xml创建
首先自然可以用记事本或其它手写,我们这里主要说用java写
XML 解析 有四种方式 1.DOM 解析 2.SAX 解析 3.JDOM解析 4.DOM4J 解析
**前两种是基础方法 ,是官方提供的解析方式,后两种是扩展的方法,需要导入JAR包
这里我们用dom4j-1.6.1.jar来写xml,该方法性能优异 , 灵活性好,功能强大,极端易用
下面是语法:
public class DemoA {
public static void main(String[] args) {
try {
//1.创建一个Document对象
Document document= DocumentHelper.createDocument();
// 添加根节点books
Element books = document.addElement("books");
// 为根节点 添加子节点book
Element book1 = books.addElement("book ");
//为子节点添加属性id=bk101
book1.addAttribute("id","bk101");
Element author = book1.addElement("author");
//在为节点添加值 <author>王珊</author>
author.setText("王珊");
Element title = book1.addElement("title");
title.setText(".NET高级编程");
Element description = book1.addElement("description");
description.setText("包含C#框架和网络编程等");
// 为根节点再添加子节点book
Element book2 = books.addElement("book ");
//为子节点添加属性
book2.addAttribute("id","bk102");
//为子节点添加子节点同时设置值
book2.addElement("author").setText("李明明");
book2.addElement("title").setText("XML基础编程");
book2.addElement("description").setText("包含XML基础概念和基本作用");
// 设置 生成 XML的格式,没有这个生成的xml会挤在一起
OutputFormat format = OutputFormat.createPrettyPrint();
//设置字符编码集
format.setEncoding("UTF-8");
File file = new File("D:\\java\\books.xml");//在D盘java下生成books.xml
if(!file.exists()){
file.createNewFile();
}
XMLWriter writer = new XMLWriter(new FileOutputStream(file),format);
writer.write(document);
writer.close();
System.out.println("XML文件生成!");
} catch (IOException e) {
e.printStackTrace();
}
}
}
生成的xml就是上面的了
三.xml读取
public class DemoB {
public static void main(String[] args) {
File file = new File("D:\\java\\books.xml");
if (file.exists()) {
try {
SAXReader reader = new SAXReader();
//读取文件 获取 Document 接口
Document document = reader.read(file);
// 获取根节点
Element root = document.getRootElement();
// 获取根节点下的子节点
List<Element> book = root.elements();
for (Element bookElem : book) {
// 当前节点名称
System.out.println(bookElem.getName());
//当前节点属性
System.out.println(bookElem.attributeValue("id"));
//当前节点下的子节点值 通过节点名称 获取节点值
System.out.println("book:"+bookElem.elementText("author"));
List<Element> list = bookElem.elements();
for (Element element:list) {
System.out.println(element.getName()+"-"+element.getText());
}
}
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
}
三.xml增删改查
给一些要用/修改的xml例子:
FullChannels.xml:
<?xml version="1.0" encoding="utf-8" ?>
<TVChannels>
<Channel>
<channelType>TypeA</channelType> <!--频道类型-->
<tvChannel>北京电视台</tvChannel> <!--频道名称-->
<path>E:\\westos\\javase\\src\\练习\\day10\\xmldocument\\北京电视台.xml</path> <!--频道对应XML文件的本地路径-->
</Channel>
<Channel>
<channelType>TypeB</channelType>
<tvChannel>凤凰卫视</tvChannel>
<path>E:\\westos\\javase\\src\\练习\\day10\\xmldocument\\凤凰卫视.xml</path>
</Channel>
</TVChannels>
以及凤凰卫视.xml部分(其它太多了没用):
<?xml version="1.0" encoding="UTF-8"?>
<typeB version=" 1.0">
<ProgramList>
<Program>
<playTime>2013-9-29 02:40</playTime> <!--播出时间-->
<name>娱乐大风暴(682) </name> <!--节目名称-->
<path>**</path> <!--节目视频的本地路径-->
</Program>
<Program>
<playTime>2013-9-29 04:25</playTime> <!--播出时间-->
<name>音乐中国风(442) </name> <!--节目名称-->
<path>**</path> <!--节目视频的本地路径-->
</Program>
</ProgramList>
</typeB>
首先是工具类,给路径数组就可以增删改查多个xml文件的简单工具类:
public class Recursion {
public static void print(List<String> s,String... strs){//String... strs,可以传入不定数字符串
for (String path:s) {//对路径数组进行循环,挨个查询xml文件
File file=new File(path);//传入xml文件路径
if (file.exists()) {
SAXReader reader = new SAXReader();
Document document= null;
try {
document = reader.read(file);
Element root=document.getRootElement();
recursion(root,strs);//传入根节点和不定数组进入迭代方法,完成增删改查
XMLWriter output = new XMLWriter(new FileOutputStream(file));//为了修改完成后的保存操作
output.write(document);
output.close();
} catch (DocumentException | IOException e) {
e.printStackTrace();
}
}
System.out.println("**********************************************");
}
}
public static void recursion(Element root,String... strs){
if(root.getText()!=null&&root.isTextOnly()){
System.out.println(root.getName()+"-"+root.getText());
if ("path".equals(root.getName())){
System.out.println();
}
}
List<Element> list=root.elements();
if (list.size()!=0){
for (Element element:list) {
if (strs.length!=0){
if ("delete".equals(strs[0])&&element.isTextOnly()&&strs[1].equals(element.getText().trim())){
root.getParent().remove(root);//删
}else if("change".equals(strs[0])&&element.isTextOnly()&&strs[1].equals(element.getText().trim())){
for (Element element1: list) {
if ("path".equals(element1.getName())){
element1.setText("C:\\音乐\\");//改
}
}
}else if("insert".equals(strs[0])&&element.isTextOnly()&&strs[1].equals(element.getText().trim())){
root=root.getParent().addElement("Program");//增(其实可以复制其他节点,然后setText,更通用点,这里这样写只能增加音乐中国风(442),固定死了,且因为格式不到位,写入的会挤在一起)
root.addElement("playTime").setText("2021-9-29 04:25");
root.addElement("name").setText("音乐中国风(442)");
root.addElement("path").setText("**");
}else {
recursion(element,strs);
}
}else {
recursion(element,strs);
}
}
}
}
}
接下来是获得xml路径,即读取
FullChannels.xml:
public class Test2 {
public static void main(String[] args) {
File file=new File("E:\\westos\\javase\\src\\练习\\day10\\xmldocument\\Fullchannels.xml");
if (file.exists()){
SAXReader reader=new SAXReader();
try {
Document document=reader.read(file);
Element root=document.getRootElement();
List<Element> channel=root.elements();
List<String> paths=new ArrayList<>();
for (Element channelElem:channel) {
List<Element> list=channelElem.elements();
for (Element element:list){
System.out.println(element.getName()+"-"+element.getText());
if("path".equals(element.getName())){
paths.add(element.getText());
}
}
System.out.println();
}
Recursion.print(paths,"delete","娱乐大风暴(682)");//删
Recursion.print(paths,"change","音乐中国风(442)");//改路径
Recursion.print(paths,"insert","音乐中国风(442)");//增
} catch (DocumentException e) {
e.printStackTrace();
}
}
}
}
修改结果:
<?xml version="1.0" encoding="UTF-8"?>
<typeB version=" 1.0">
<ProgramList>
<Program>
<playTime>2013-9-29 04:25</playTime> <!--播出时间-->
<name>音乐中国风(442) </name> <!--节目名称-->
<path>C:\音乐\</path> <!--节目视频的本地路径-->
</Program>
<Program><playTime>2021-9-29 04:25</playTime><name>音乐中国风(442)</name><path>**</path></Program></ProgramList>
</typeB>