XML的全称为(eXtensible Markup Language),是一种可扩展的标记语言。
标记语言:通过标签来描述数据的一门语言
可扩展:标签的名字是可以自定义的
XML被设计用来存储和传输数据。
不同软件之间进行数据传输。
存储数据供软件使用。
XML组成-文档声明格式
version:版本号,该属性是必须存在的
encoding:文件编码,该属性不是必须的(一般取值都是UTF-8)
文档声明必须是XML第一行
注释
标签
<name>catname>
属性
<person id="1" student="true">person>
实体字符
< 是 < ;>是> ;
<note>
1<2
2>1
note>
字符数据区
快捷键:CD
<note2>
1
]]>
note2>
注意事项:
1.标签要成对出现,有前有后,后面的多一个斜杠
2.如果中间没有内容,可以在前面的标签上加上/表示提前结束这个标签
3.不要有嵌套标签
4.最外层只能有一个根标签
5.有些特殊字符需要转义,或者使用CD转义字符区标记
<Objperson>
<person id="1" student="true">
<name>catname>
<age>18age>
<address>地球address>
<note>
1<2
2>1
note>
<note2>
1
]]>
note2>
<email/>
person>
Objperson>
因为XML文件的标签和属性可以随意扩展,通过XML约束来限定XML文件中可使用的标签以及属性。
DTD约束,比较简单,功能相对弱
Schema,比较复杂,功能相对强
XML的解析就是读取XML中的数据
SAX解析
DOM解析
DOM解析原理
一次性读取XML中的所有数据,在内存中形成一颗DOM树
Person类
public class Person {
private int id;
private boolean vip;
private String name;
private String gender;
private String email;
public Person() {
}
public Person(int id, boolean vip, String name, String gender, String email) {
this.id = id;
this.vip = vip;
this.name = name;
this.gender = gender;
this.email = email;
}
将数据解析并存入List
// 我要经常得到XML的数据
// 1.每次都解析,效率低,代码很繁琐
// 2.解析一次,把得到的数据保存到对象中,以后只要获取对象中的数据
public class Demo01 {
public static void main(String[] args) throws DocumentException {
//创建一个List将解析得到的数据存入
ArrayList<Person> arrayList = new ArrayList<>();
// 1.创建解析器
SAXReader sr = new SAXReader();
// 2.使用解析器解析XML, 在内存中形成DOM树
Document document = sr.read(new File("D:\\it_workspace\\JavaSE_进阶\\study_day14\\04_解析XML\\Contact.xml"));
// getRootElement: 获取根元素
Element rootElement = document.getRootElement();
// getName(): 获取元素名称
String name = rootElement.getName();
System.out.println("根元素:" + name);
// element(name): 获取一个指定名称的子元素,如果有多个返回第一个
Element element1 = rootElement.element("contact");
System.out.println("第一个:" + element1.getName());
// attributeValue(属性名): 通过属性名得到属性值
String id = element1.attributeValue("id");
String vip = element1.attributeValue("vip");
System.out.println(id + vip);
// elements(): 获取所有子元素
List<Element> elements = rootElement.elements();
for (Element element : elements) {
System.out.println(element.getName());
System.out.println(element.attributeValue("id"));
System.out.println(element.attributeValue("vip"));
}
System.out.println("--------------------");
// elements(name): 获取所有指定名称的子元素
List<Element> contacts = rootElement.elements("contact");
for (Element contact : contacts) {
System.out.println(contact.getName());
String id1 = contact.attributeValue("id");
String vip1 = contact.attributeValue("vip");
System.out.println(id1 + vip1);
// elementText(子元素): 得到子元素的文本
String name1 = contact.elementText("name");
String gender = contact.elementText("gender");
String email = contact.elementText("email");
System.out.println(id1 + vip1 + name1 + gender + email);
//数据类型转换
int i = Integer.parseInt(id1);
boolean b = Boolean.parseBoolean(vip1);
Person person = new Person(i, b, name1, gender, email);
arrayList.add(person);
}
System.out.println("--------------------");
for (Person person : arrayList) {
System.out.println(person);
}
}
}
XPath使用路径表达式来选取XML文档中的元素节点或属性节点。节点是通过沿着路
径 (path) 来选取的。XPath在解析XML文档方面提供了一独树一帜的路径思想。
XPath使用步骤
导入jar包(dom4j和jaxen-1.1.2.jar)
通过dom4j的SAXReader获取Document对象
利用XPath提供的API,结合XPath的语法完成选取XML文档元素节点进行解析操作。
public class Demo02 {
public static Document document = null;
//提前加载资源且只用加载一次所以用BeforeClass
@BeforeClass
public static void testBeforeClass() throws DocumentException {
//dom4j
SAXReader sr = new SAXReader();
//junit里的相对路劲是不带模块名的
//绝对路径绝不会错
document = sr.read(new File("D:\\it_workspace\\JavaSE_进阶\\study_day14\\04_解析XML\\Contact.xml"));
}
// XPath:绝对路径
@Test
public void test01() {
// 定义 XPath 表达式:/contactList/contact/name
// 调用Document对象的selectNodes()方法执行XPath获得节点
List<Node> nodes = document.selectNodes("/contactList/contact/name");
for (Node node : nodes) {
System.out.println(node.getName()+""+node.getText());
}
}
// XPath:相对路径, 以调selectNodes方法用者作为参照往后找
@Test
public void test02() {
// 获得根节点对象
Element rootElement = document.getRootElement();
// 定义 XPath 表达式:./contact/name
// 调用Document对象的selectNodes()方法执行XPath获得节点
List<Node> nodes = rootElement.selectNodes("./contact/name");
for (Node node : nodes) {
System.out.println(node.getName()+node.getText());
}
}
// XPath:全文搜索
@Test
public void test03() {
// 创建XPath表达式: //name
List<Node> nodes = document.selectNodes("//name");
// 调用Document对象的selectNodes()方法执行XPath获得节点
// List nodes = document.selectNodes("//name");
for (Node node : nodes) {
System.out.println(node.getName()+":"+node.getText());
}
}
// XPath:属性查找 //@属性名 全文搜索属性,返回的是属性对象
@Test
public void test04() {
// 创建XPath表达式: //@id 获取所有的id属性
// 调用Document对象的selectNodes()方法执行XPath获得节点
List<Node> nodes = document.selectNodes("//@id");
for (Node node : nodes) {
System.out.println(node.getName()+":"+node.getText());
}
}
// XPath:属性查找 //元素[@属性名] 查找具有指定属性名的元素
@Test
public void test05() {
// 创建XPath表达式: //contact[@vip] 获取包含vip属性的contact元素
// 调用Document对象的selectNodes()方法执行XPath获得节点
List<Node> nodes = document.selectNodes("//contact[@id='1']");
for (Node node : nodes) {
Element node1 = (Element) node;
System.out.println(node1.elementText("name"));
System.out.println(node.getName());
}
}
}
如果你对本文有疑问,你可以在文章下方对我留言,敬请指正,对于每个留言我都会认真查看。