XML文档
一、概念
1.1 基础概念
- 概念:用于框架或者一些全局的配置文件,用来将一些全局的数据配置在xml文档中,整个工程都能解析出来xml文档中的数据。比如:C3P0连接池,里面的c3p0config.xml文件就是作用全局的配置文件。一般配置数据源和参数等。xml配置文件在框架中必用。
- 其他的配置文件:properties、txt文档
需要引入xml配置文件的必要性:主要是在一般业务逻辑中,不会是简单的键值对数据,而是有关系的层级数据,只能使用xml配置文件进行配置。
1.2 文档举例
-- 举例说明层级关系
<city>
<四川>
<成都>cd</成都>
<绵阳>my</绵阳>
<宜宾>yb</宜宾>
</四川>
<重庆>
<渝北>yb</渝北>
<江北>jaingbei</江北>
</重庆>
</city>
1.3 编写示例文档
<?xml version="1.0" encoding="utf-8" ?>
<city>
<四川>
<成都>cd</成都>
<绵阳>my</绵阳>
<宜宾>yb</宜宾>
</四川>
<重庆>
<渝北>yb</渝北>
<江北>jaingbei</江北>
</重庆>
</city>
1.4 xml文档组成部分(了解)
组成部分:声明、自定义标签(元素)、属性(写在开始标签之间的)、内容部分(两个尖括号之间的文本)、转义字符、CDATA区
声明:必须放在xml文件的第一行,在它之前连注释都不能有
<?xml version="1.0" encoding="utf-8" ?>
注释:在正常开发中,必须有注释
在xml文件中编写注释内容
<!--注释内容-->
自定义标签,:xml文档是可扩展的标记语言,标签可以随意写任何内容,只要是前后一致,开始标签+结束标签,结束标签要加/
<name></name>
<age></age>
属性:放在开始标签里面的,用来标记该标签的内容
// 其中name表示属性,等号里面跟的是属性值
<property name="url">jdbc:mysql://localhost:3306/shop</property>
内容部分:在两个标签之间,编写一些文本内容
<name>张三</name>
<age>18</age>
转义字符:在xml文档中,用转义标签一些特殊的符号,在页面显示出来对应的符号
<name>></name>-----><name>></name>
&
>
<
二、解析XML文档(重点)
2.1 XML解析方式
方式1:DOM解析
特点:不管代码中是否要全部使用,都会一次性将所有内容解析成文档树,存储在内存中,提高查询效率,缺点是会造成内存的占用。
- 方式2:SAX解析
特点:按需解析,需要什么样数的数据,每一次解析一部分,如果找到了需要的内容,则不再解析。缺点:效率较低。优点:节约内存
2.2 使用java代码解析xml文件
- 使用的类:
DocumentBuilderFactory类:工厂类,需要通过newInstance()方法获取一个工厂对象
DocumentBuilder类:解析xml文档的类,通过工厂对象调用newDocumentBuilder()方法获得
Document类:文档树,存储在内存中的文档树,通过解析类对象调用parse()获得。
2.2 获取文本内容的示例代码
public class Demo1 {
public static void main(String[] args) throws Exception{
//1、创建文档工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2、通过工厂对象获取解析对象
DocumentBuilder builder = factory.newDocumentBuilder();
//3、通过解析文档对象获取文档树对象
Document document = builder.parse(new File("src/user.xml"));
//从document文档树中获取数据.NodeList里面存的都是Node对象
NodeList list = document.getElementsByTagName("userName");
//调用item(index),表示从里面获取第几个标签,得到的是Node对象
Node node = list.item(0);
//获取标签之间的文本内容
String text = node.getTextContent();
System.out.println(text);
}
}
2.3 读取xml配置文件步骤
- 步骤1:获取工厂对象
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
- 步骤2:通过工厂对象,获取解析对象
DocumentBuilder builder = factory.newDocumentBuilder();
- 步骤3:通过解析对象,将xml文档解析成文档树存储在内存中
Document document = builder.parse(new File(“路径”));
- 步骤4:操作document对象,通过标签名获取节点列表对象
NodeList list = document.getElementsByTagName(“标签名称”);
- 步骤5:一般都是为了获取标签之间的文本内容,获取文本内容使用getTextContent();
String text = list.item(index).getTextContent();
2.4 xml文档的其他操作
如果用程序对xml文件进行增、删、改操作,必须使用Transformer对象进行将内存中的内容更新到硬盘中。
2.4.1 修改xml文档
```java public class UpdateXML { public static void main(String[] args) throws Exception{
//1、获取工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//2、获取解析对象
DocumentBuilder builder = factory.newDocumentBuilder();
//获取文档树
Document document = builder.parse(new File("src/user.xml"));
//将李四改成:李雷,将张三改成:李华
document.getElementsByTagName("userName").item(0).setTextContent("李华");
document.getElementsByTagName("userName").item(1).setTextContent("李雷");
//创建TransformerFactory对象
TransformerFactory tf = TransformerFactory.newInstance();
Transformer former = tf.newTransformer();
/*
* transform(Source xmlSource, Result outputTarget)
* xmlSource:指的是内存中的document文档树源
* outputTarget:对应的更新硬盘中的xml文件
*/
former.transform(new DOMSource(document), new StreamResult(new File("src/user.xml")));
} }
<a name="JeUIT"></a>
### 2.4.2 对xml文档新增内容(一)
- 如果使用父目录标签名中的方法:appendChild(element)在一个父目录下的最后位置添加新的元素和文本内容
```java
public class OtherXML {
//向xml文档中新增一个标签及内容
@Test
public void addElement() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/user.xml"));
//新增元素(标签):相当于在xml文件中新增一个<password></password>
Element element = document.createElement("password");
//设置标签之间的文本内容
element.setTextContent("admin");
//将创建好的标签及内容挂载到父目录下
Node parent = document.getElementsByTagName("u1").item(0);
//在父目录标签下,添加一个孩子标签
parent.appendChild(element);
//将内存中的内容更新到硬盘中
TransformerFactory tf = TransformerFactory.newInstance();
Transformer former = tf.newTransformer();
former.transform(new DOMSource(document), new StreamResult(new File("src/user.xml")));
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.4.3 在xml文档中的任意位置添加新的标签及内容(二)
public class OtherXML {
//向xml文档中任意位置添加新的标签及内容
@Test
public void addElement2() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/user.xml"));
//新建一个标签
Element element = document.createElement("address");
element.setTextContent("重庆");
//获取要添加在哪个标签之前的兄弟标签
Node node = document.getElementsByTagName("age").item(0);
Node parent = document.getElementsByTagName("u1").item(0);
//在node标签之前添加进去,父标签添加子标签,要指定在该标签下的哪个标签之前添加
//第一个参数:要添加的新标签及内容
//第二个参数:指定哪个标签之前添加
parent.insertBefore(element, node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer former = tf.newTransformer();
former.transform(new DOMSource(document), new StreamResult(new File("src/user.xml")));
} catch (Exception e) {
e.printStackTrace();
}
}
}
2.4.4 删除xml文档中的指定标签
public class OtherXML {
//删除某个节点
@Test
public void delete() {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new File("src/user.xml"));
//获取要删除的标签(节点)
Node node = document.getElementsByTagName("address").item(0);
//删除
node.getParentNode().removeChild(node);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer former = tf.newTransformer();
former.transform(new DOMSource(document), new StreamResult(new File("src/user.xml")));
} catch (Exception e) {
e.printStackTrace();
}
}
}