##XML及其解析
第一节、XML的基础语法
1.0、什么是XML
1、Extensible Markup Language 可扩展的标记语言
2、可扩展的含义—指用于可以扩展标签 ,用户可以自定义标签
3、XML是一种文本语言
(类似于JSON),文本语言可以独立于不同的操作系统以及编程语言。
应用场景:1、用于数据的传输 2、保存一些程序的配置信息(主要用)
1.1、XML文件基本语法
1、每一个XML文件必须以.xml结尾
2、每一个XML文件的第一句代码一定是:
<?xml version="1.0" encoding="utf-8"?>
3、每一个XML文件都必须有且只有一个最顶层标签(根元素),其他的标签都应该放在根元素中.。
4、每一个标签都有对应的结束标签,标签内容就放在开始标签和结束标签中间
<student>内容 </student>
注意:内容–可以文本,可以是其他的标签
5、标签命名不能以数字和特殊符号开头,标签名是大小写敏感
<STUDENT></student>
6、注释的写法(和HTML中一样)
<!--注释内容-->
7、每一个标签上可以带有属性
####1.3、定义一个描述学生信息的XML文件
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1">
<stu-name>tom</stu-name>
<stu-score>30</stu-score>
</student>
<student id="2">
<stu-name>JERRY</stu-name>
<stu-score>59</stu-score>
</student>
</students>
问题:过于灵活 ,不便于维护,做一些限制
<?xml version="1.0" encoding="utf-8"?>
<students>
<student id="1">
<stu-name>tom</stu-name>
<stu-score>30</stu-score>
</student>
<student id="2">
<stu-name>JERRY</stu-name>
<stu-score>59</stu-score>
</student>
<student>
<name>JERRY</name>
<score>59</score>
</student>
</students>
问题:传输数据通过上述方式传递,但是取数据的时候不好取。
第二节、XML的约束
XML的约束为了解决上述问题,对这个XML文件做一定的限制,保证数据正确的传递与解析。
常见XML约束DTD,XSD
DTD:DOCUMENT TYPE DEFINITION 文档类型定义
作用:用于约束XML的编写
基本语法:
<!ELEMENT 需要约束的标签 (子标签名1,子标签名2,...)> <!ATTLIST 需要约束的标签 属性名 #REQUIRED (必须的)/#IMPLEMT (可选的)>
在XML中定义DTD
基本语法
<!DOCTYPE root[
<!ELEMENT 元素名 (子元素)>
<!ELEMENT 元素(stu-name,stu-score)>
<!ATTLIST 元素 属性名 值>
]>
练习:指定一个DTD ,约束students xml 要求:根源素 students 根元素下至少有一个子元素且名字student student下子元素名叫name age score
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE teachers[
<!ELEMENT teachers (teacher+)>
<!ATTLIST teacher id CDATA #REQUIRED>
<!ELEMENT teacher (name,age,salary)>
<!ELEMENT name (#PCDATA)>
]>
<teachers>
<teacher id="1">
<name>
123
</name>
<age>12</age>
<salary>1000</salary>
</teacher>
</teachers>
总结:
1、根元素中约束子元素个数
? 0个或者1个
* 任意多个
+ 1个或者多个
2、约束元素中填文本还是可以其他特殊符号
<!ELEMENT name (#PCDATA)> 值为PCDATA
3、约束属性
<!ATTLIST teacher id CDATA #REQUIRED> 属性必须出现
type CDATA #IMPLIED 属性可有可无
第三节、XML的解析
所谓XML的解析,其实就是对XML文件进行操作。(增加,删除,修改,查询)
市面上常见的XML解析的方式:
DOM解析:
DOCMENT OBJECT MODEL 文档对象模型。
特点:每次解析的时候会将整个XML文件读进程序,然后进行解析。
问题:内存压力大,适用于文件较小
SAX解析:
特点:局部解析,每次解析XML文件时候不用全部将XML文件加载进程序。
问题:每次需要定位,然后在读取进程序,但是对于内存压力较小,适用于较大文件的解析。
DOM4J(for java):学习使用
dom4j是一个Java的XML API,是jdom的升级品,用来读写XML文件的。dom4j是一个十分优秀的JavaXML API
DOM4J解析XML文件环境搭建:
1.导入对应的JAR包
2.准备XML
<?xml version="1.0" encoding="utf-8"?>
<books>
<book id="1">
<bookName>红楼梦</bookName>
<bookPrice>12</bookPrice>
</book>
<book id="2">
<bookName>金瓶梅</bookName>
<bookPrice>20</bookPrice>
</book>
<book id="3">
<bookName>西游记</bookName>
<bookPrice>22</bookPrice>
</book>
</books>
3.通过DOM4J解析(读取)XML文档
-
创建一个SAXReader xml的读取器
SAXReader saxReader = new SAXReader();
SAXReader()作用:有一个read方法将输入流转为DOM对象
Document doc = saxReader.read(new FileInputStream("src/Book.xml"));
-
准备输入流(将文件与程序之间建立通道)
-
saxReader.read(输入流)
-
解析dom模型
Document对象:XML的DOM结构描述对象
-
获取根元素(根元素是所有元素的入口)
doc.getRootElement();
Iterator<Element> el2 = el1.elementIterator();//元素下资源的迭代器 Iterator<Attribute> el3 = el1.attributeIterator();//元素上的属性的迭代器
-
取元素值 (节点下方法)
-
System.out.println(e.getName()+"===>"+e.getStringValue());
-
获取属性值:
while(el3.hasNext()) {
Attribute next = el3.next();
System.out.println(next.getName()+"===>"+next.getStringValue());
}
3.2、元素添加
1、父元素对象.addElement(“元素名”)
作用:创建一个对应元素并添加至父元素
2、元素.addAttribute(“属性名”,“属性的值”)
作用:在指定元素添加属性
3、将Document对象写出到XML文件中
XMLWriter.write(document)
作用:将指定的document写成XML文件
创建XMLWriter对象
1.new XMLWriter(Writer, OutputFormat)–以字符往外写
1.new XMLWriter(OutPutStream, OutputFormat)–以字节往外写
注意:如果是字符往外写,就需要对字符输出流进行编码
OutputFormat输出格式
OutputFormat对象得到,该类2个静态方法
createPrettyPrint()--创建一个漂亮的输出格式 createCompactFormat()--创建一个压缩的输出格式
//思路:1.将文件转成Document对象
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(new FileInputStream("src/Book.xml"));
// 2.对document对象操作
Element root = doc.getRootElement();
Element sonElement = root.addElement("book");
sonElement.addAttribute("id", "5");
Element bookElement = sonElement.addElement("bookName");
bookElement.setText("杀人书");
Element priceElement = sonElement.addElement("bookPrice");
priceElement.setText("1350");
//3.将document对象写出对应XML文件
//OutputFormat 输出流的格式
//createPrettyPrint()--创建一个漂亮的输出格式
//createCompactFormat()--创建一个压缩的输出格式
OutputFormat compactFormat = OutputFormat.createCompactFormat();
compactFormat.setEncoding("utf-8"); //对输出格式进行编码
//四大基类
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/Book.xml"),compactFormat);
xmlWriter.write(doc);//将document写出到指定路径
xmlWriter.close();
工具类封装
//将DOC写成XML文件的工具方法
public static void writeXML(Document doc,String url) {
//创建OutPutFormate对象
OutputFormat of = OutputFormat.createPrettyPrint();
//设置编码
of.setEncoding("utf-8");
//创建XMLWriter对象
try {
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(url), of);
xmlWriter.write(doc);
xmlWriter.close();
} catch (UnsupportedEncodingException | FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Document getDocumentByUrl(String url) {
SAXReader saxReader = new SAXReader();
Document doc = null;
try {
doc = saxReader.read(url);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return doc;
}
3.3、元素的删除
父元素.romove(子元素)
核心:
1.找到需要删除的节点以及删除节点的父节点
找到删除节点:解析DOM对象
找到父节点:子节点.getParent();
Element root = doc.getRootElement();
Iterator<Element> rootit = root.elementIterator();
while(rootit.hasNext()) {
Element son = rootit.next();
Iterator <Element> sonson = son.elementIterator();
while(sonson.hasNext()) {
Element next = sonson.next();
//判断该元素的value是否是tom
if("tom".equals(next.getStringValue())) {
//删除
Element del = next.getParent();//student节点(待删除的节点)
del.getParent().remove(del);
}
}
}
创建XML文件
核心:没有XML文件,需要手动创建DOM对象
doucmentHelpe创建
Document doc = DocumentHelper.createDocument();//创建一个DOM对象
对DOM对象操作
Document doc = DocumentHelper.createDocument();//创建一个DOM对象
//2.操作DOM对象
Element root = doc.addElement("students");
Element stu1 = root.addElement("student");
stu1.addElement("name").setText("小明");
//3.写出去
WriteXMLUtil.writeXML(doc, "src/stu.xml");
System.out.println("执行成功");
第四节:XPath
XPath是一门专门用于查找XML文档信息的标记(语言),我们可以指定特定路径进行查找。解决了传统需要遍历查找元素的效率问题。
环境搭建:需要 jaxen-1.1-beta-8.jar
常见表达式:
- nodeName 找根元素
- 父元素/子元素 找父元素下子元素
- 父元素//后代元素 找祖先元素的后代元素
//含义 students 元素下 找所有的student子元素下面的stu-name儿子元素
//List<Element> selectNodes = doc.selectNodes("students//student/stu-name");
//在元素下找子元素
//List <Element>selectNodes = doc.selectNodes("//student");
//在根元素下找指定下标的子元素
//List <Element>selectNodes = doc.selectNodes("//student[1]");
//在根元素下找指定student元素的最后一个元素
//List <Element>selectNodes = doc.selectNodes("//student[last()]");
//在根元素下找student倒数第二个
//List <Element>selectNodes = doc.selectNodes("//student[last()-1]");
//在根元素下找student 位置小于3的 (position从1开始)
//List <Element>selectNodes = doc.selectNodes("//student[position()<3]");
//找id属性为2
//List <Element>selectNodes = doc.selectNodes("//student[@id='2']");
//找具有id属性的student
List <Element>selectNodes = doc.selectNodes("//student[@id]");