XML简介
- XML是指可扩展标记语言(eXtensible Markup Language),是一种标记语言,很类似HTML,它被设计的宗旨是传输数据,而非显示数据
- XML标签没有被预定义,需要用户自定义标签
- XML技术是W3C组织发布的
XML的应用
-
不同系统之间传输数据
-
用来表示生活中有关系的数据
-
经常用在配置文件中
XML的文档声明
-
创建文件的后缀名是
.xml
-
如果要写一个xml文件,第一步必须要有文档声明,表示写的是xml文件
<?xml version="1.0" encoding="gbk"?>
,文档声明必须写在第一行第一列,version属性表示版本,有1.0和1.1,一般使用1.0,encoding属性表示编码,另一个属性standalone,表示是否需要依赖其他文件,若需要写standalone=“yes”,不需要standalone=“no”
XML的中文乱码问题解决
设置保存时候的编码方式和打开时的编码方式一致即可
XML元素(标签)的定义
-
标签定义有开始必须要有结束,
<person></person>
-
如果标签没有内容,可以在标签内结束,如:
<person/>
-
标签可以嵌套,如:
<a><b></b></a>
-
一个xml文件中必须要有且仅有一个根标签,其它的标签都是这个标签下的标签
-
对于xml标签中出现的所有空格和换行,xml解析程序都会当做标签内容来处理
-
xml中标签的命名规则
(1)xml代码区分大小写
(2)标签名称不能以数字或_开头
(3)xml的标签不能以XML、xml、Xml等开头
(4)标签不能包含空格和冒号
(5)xml的标签可以是中文
XML中属性的定义
xml是标记型文档,可以有属性,如:<person id="aaa"></person>
属性定义的要求:
-
一个标签上可以有多个属性
-
属性值要用引号(单引号或双引号)引起来
-
属性名称的命名规范与标签名称的命名规范一样
xml的注释
<!--这是注释-->
,xml中注释不能嵌套
xml的特殊字符
需要对特殊字符进行转义才能正常显示,如要显示a<b,可以写成a<b
,>用>
转义,双引号用"
转义,单引号用'
转义
xml的CDATA区
如果有多个字符都需要转义,可以把它们整体放到CDATA区里,就不需要转义了
写法:<![CDATA[内容]]>
xml的PI指令(处理指令)
作用:用来指挥软件如何解析xml文件,可以设置样式(一般没啥用)
xml-stylesheet指令:<?xml-stylesheet type="text/css" href="#"?>
,只能对英文标签名称起作用
xml的约束简介
比如现在定义一个person的xml文件,只想要在这个文件里面保存人的相关信息,但是在xml文件中写了一个<猫>标签,虽然可以正常显示,但它不是人的信息,这时需要技术来规定xml中只能出现的元素,这就是约束。xml中的约束技术:dtd约束、schema约束
-
dtd快速入门(能看懂就行)
(1)创建dtd文件,后缀名为.dtd
(2)xml文件中有几个元素,就在dtd文件中写几个<!ELEMENT>
(3)复杂元素(有子元素)写法:<!ELEMENT 元素名称 (子元素1,子元素2)>
(4)简单元素(无子元素)写法:<!ELEMENT 元素名称 (#PCDATA)>
(5)在xml文件中引入dtd文件,<!DOCTYPE 根元素名称 SYSTEM "dtd文件的路径">
(6)用浏览器打开xml文件,浏览器只校验语法,不校验约束,需要使用工具来校验约束 -
dtd的引入方式
(1)引入外部dtd文件,<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
(2)使用内部dtd文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE person [
<!ELEMENT person (name,age)>
<!ELEMENT name (#PCDATA)>
<!ELEMENT age (#PCDATA)>
]>
<person>
<name>zhangsan</name>
<age>20</age>
</person>
(3)从公共网络上引入dtd文档,<!DOCTYPE 根元素名称 PUBLIC "dtd名称" "dtd文档的url">
-
在dtd文档中使用ELEMENT关键字来声明一个XML元素
(1)语法:<!ELEMENT 元素名 使用规则>
(2)简单元素约束例如:<!ELEMENT name (#PCDATA)>
,其中, (#PCDATA)约束name是字符串类型,若为EMPTY,则约束<name></name>
中内容为空,若为ANY,则可空也可不空
(3)复杂元素约束如:<!ELEMENT person (name,age)>
表示子元素出现的次数:若写成name+,表示name可以出现一次或多次;若写成age?,表示age可以出现0次或1次;若写成name*,表示name可以出现0次或1次或多次。在<!ELEMENT person (name,age)>
中元素之间用逗号隔开,并且有顺序,若用 | 隔开,则表示这些子元素只能出现其中的任意一个 -
使用dtd定义属性
语法:
<!ATTLIST 元素名称
属性1名称 属性类型 属性的约束
属性2名称 属性类型 属性的约束
>
属性类型:
CDATA:表示属性的取值为普通的文本字符串
枚举:只能从枚举列表中任选其一,如(鸡肉|牛肉|鱼肉)
ID:表示属性的取值不能重复,属性的值只能由字母、下划线开头,不能出现空白字符
属性约束设置说明:
#REQUIRED:表示该属性必须出现
#IMPLIED:表示该属性可有可无
#FIXED:表示属性的取值为一个固定值,语法:#FIXED "固定值"
直接值:表示属性的取值为该默认值,若不写属性,则使用直接值,若写属性,则使用设置的那个值
- 定义实体
概念:在dtd中定义,在xml中使用
语法:<!ENTITY 实体名称 "实体内容">
引用方式:&实体名称;
如在dtd中定义:<!ENTITY test "haha">
在xml中使用:<name>&test;</name>
注意:定义实体一般写在内部dtd中,如果写在外部dtd里面,在某些浏览器下,内容得不到
xml的解析的简介
-
js使用dom解析HTML文档:根据HTML的层级结构,在内存中分配一个树形结构,把HTML的标签、属性和文本都封装成对象,有document对象、属性对象、文本对象、Node节点对象等
-
xml的解析方式(技术):dom和sax
(1)使用dom方式解析xml时,如果文件过大,会造成内存溢出,但可以很方便的实现增删改操作
(2)sax解析过程:采用事件驱动,边读边解析(一行一行地解析,解析到某一个对象,把对象名称返回)。这种解析方式不会造成内存溢出,可以方便实现查询,但不能实现增删改操作 -
想要解析xml,首先需要解析器,不同的公司和组织提供了针对dom和sax方式的解析器,通过api的方式提供。如sun公司的jaxp,dom4j组织的dom4j(实际开发中使用最多),jdom组织的jdom
jaxp的api的查看
-
JAXP:(Java API for XML Processing)开发包是JavaSE的一部分,它由以下几个包及其子包组成
org.w3c.dom:提供DOM方式解析XML的标准接口
org.xml.sax:提供SAX方式解析XML的标准接口
javax.xml:提供了解析XML文档的类 -
javax.xml.parsers包中,定义了几个工厂类,我们可以通过调用这些工厂类,得到对XML文档进行解析的DOM和SAX解析器对象
(1)针对dom:DocumentBuilder(解析器类)、DocumentBuilderFactory(解析器工厂)
DocumentBuilder:这是个抽象类,不能new,此类的实例可以从DocumentBuilderFactory.newDocumentBuilder()方法获取。这里面有一个方法parse(“xml的路径”)可以解析xml,返回的是Document整个文档,Document是个接口,其父接口是Node,如果在Document里面找不到想要的方法,可以到Node中去找。在Document中有个方法getElementByTagName(String tagname),这个方法可以得到标签,返回集合NodeList,还有创建标签的方法createElement(String tagname),创建文本的方法createTextNode(String data),Node里面有appendChild(Node newChild)方法可以添加节点
DocumentBuilderFactory:这也是个抽象类,不能new,newInstance()方法获取实例
(2)针对sax:SAXParser(解析器类)、SAXParserFactory(解析器工厂)
使用jaxp查询节点
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
</p1>
<p1>
<name>lisi</name>
<age>25</age>
</p1>
</person>
需求:查询xml中所有的name元素的值
package packagetest;
import java.io.IOException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class classtest {
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException {
//查询所有name元素的值
/* 1、创建解析器工厂
* 2、根据解析器工厂创建解析器
* 3、解析xml返回Document
* 4、得到所有的name元素
* 5、返回集合,遍历集合,得到每一个name元素
*
*/
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
NodeList list=document.getElementsByTagName("name"); //得到name元素
for(int i=0;i<list.getLength();i++) {
Node name1=list.item(i); //得到每一个name元素
String s=name1.getTextContent(); //得到标签里面的内容
System.out.println(s);
}
}
}
使用jaxp查询某一个节点
若要获取第一个节点值,可使用代码
Node name1=list.item(0);
String s=name1.getTextContent();
System.out.println(s);
使用jaxp添加节点
需求:在上面第一个<p1></p1>
中添加一个sex
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
NodeList list=document.getElementsByTagName("p1"); //得到所有的p1
Node p1=list.item(0); //得到第一个p1
Element sex1=document.createElement("sex"); //创建标签
Text text1=document.createTextNode("nv"); //创建文本
sex1.appendChild(text1); //把文本添加到sex1下面
p1.appendChild(p1); //把sex1添加到p1下面
//回写xml
TransformerFactory transformerFactory=TransformerFactory.newInstance();
Transformer transformer=transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
使用jaxp修改节点
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
<sex>nv</sex>
</p1>
<p1>
<name>lisi</name>
<age>25</age>
</p1>
</person>
需求:修改nv为nan
-
创建解析器工厂
-
根据解析器工厂创建解析器
-
解析xml,返回Document
-
得到sex,使用item()方法
-
修改sex里面的值,setTextContent()方法
-
回写xml
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
Node sex1=document.getElementsByTagName("sex").item(0); //得到sex1
sex1.setTextContent("nan"); //修改sex的值
//回写xml
TransformerFactory transformerFactory=TransformerFactory.newInstance();
Transformer transformer=transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
使用jaxp删除节点
需求:删除上面的sex节点
-
创建解析器工厂
-
根据解析器工厂创建解析器
-
解析xml,返回Document
-
获取sex元素
-
获取sex的父节点
-
使用父节点删除,removeChild()方法
-
回写xml
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
Node sex1=document.getElementsByTagName("sex").item(0); //得到sex1
Node p1=sex1.getParentNode(); //得到父节点
p1.removeChild(sex1);
//回写xml
TransformerFactory transformerFactory=TransformerFactory.newInstance();
Transformer transformer=transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
jaxp遍历节点
需求:打印出所有标签的名称
-
创建解析器工厂
-
根据解析器工厂创建解析器
-
解析xml,返回Document
-
得到根节点及其子节点,使用递归实现
public static void main(String[] args) throws Exception {
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance(); //创建解析器工厂
DocumentBuilder builder=builderFactory.newDocumentBuilder(); //创建解析器
Document document=builder.parse("src/1.xml"); //解析xml返回Document
list1(document);
}
//递归遍历
public static void list1(Node node) {
if(node.getNodeType()==Node.ELEMENT_NODE) { //判断元素类型再打印,不打印空格等
System.out.println(node.getNodeName());
}
NodeList list=node.getChildNodes(); //得到一层子节点
for(int i=0;i<list.getLength();i++) { //遍历list
Node node1=list.item(i); //得到每一个节点
node1.getChildNodes(); //继续得到node1的子节点
list1(node1);
}
}
schema约束
-
XML Schema也是一种定义和描述XML文档结构与内容的模式语言,其出现是为了克服DTD的局限性
XML Schema vs DTD:
(1)XML Schema符合XML语法结构
(2)DOM、SAX等XML API很容易解析出XML Schema文档中的内容
(3)XML Schema对名称空间支持得非常好
(4)XML Schema比XML DTD支持更多的数据类型,并支持用户自定义新的数据类型
(5)XML Schema定义约束的能力非常强大,可以对XML示例文档做出细致的语义限制
(6)XML Schema不能像DTD一样定义实体,比DTD更复杂,但XML Schema现在已是w3c组织的标准,它正逐步替代DTD
(7)一个xml中只能有一个dtd,但可以有多个schema,多个schema使用名称空间区分 -
schema快速入门
(1)XML Schema文件自身就是一个XML文件,但它的扩展名通常为.xsd
。和XML一样,XML Schema文档必须也有一个根节点,但这个根节点的名称为Schema
(2)编写了XML Schema约束文档之后,通常需要把这个文件中声明的元素绑定到一个URI地址上,这个URI地址叫namespace名称空间,以后XML文件就可以通过这个URI引用绑定指定名称空间的元素
(3)在schema文件里面,xmlns="http://www.w3.org/2001/XMLSchema"
属性表示当前文件是一个约束文件。targetNamespace="2019/4/17"
引号里面的地址可以随便写,使用时通过这个地址引入约束文件。还有一个属性elementFormDefault="qualified"
表示质量良好
(4)在xml文件中有几个元素,在schema文件中就写几个元素,简单元素写在sequence里面,表示元素出现的顺序。下面分别是xml文件和schema文件
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>zhangsan</name>
<age>20</age>
</person>
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="2019/4/17"
elementFormDefault="qualified">
<element name="person">
<complexType>
<sequence>
<element name="name" type="string"></element>
<element name="age" type="int"></element>
</sequence>
</complexType>
</element>
</schema>
(5)在xml文件中引入schema文件
<?xml version="1.0" encoding="UTF-8"?>
<person xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="2019/4/17"
xsi:schemaLocation="2019/4/17 1.xsd">
<name>zhangsan</name>
<age>20</age>
</person>
上面代码中,xmlns后面跟个:xsi
表示给xmlns起个别名,xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
表示这是个被约束文件,上面的1.xsd
处写约束文档的路径
schema约束的api的查看
-
XML Schema复杂元素指示器
All:表示只能出现一次
Choice:只能出现其中一个
Sequence:元素按照顺序出现
maxOccurs="unbounded"指示元素出现次数,unbounded表示出现次数没有限制,<element name="name" type="double" maxOccurs="unbounded"/>
<any></any>
表示里面可以写任意元素 -
schema里面定义属性(必须是复杂元素)
写在</complexType>
前面
写法:<attribute name="id1" type="int" use="required></attribute>"
,name表示属性名称,type表示属性类型,use表示属性是否必须要出现(required表示属性必须要出现) -
若要引入多个schema文件,可以给每个schema起一个别名,引用方式
schema的别名:元素名称
,如:<dept:name>100</dept:name>
sax的解析过程
事件驱动方式,边读边解析
-
在
javax.xml.parsers
包里面有两个类:SAXParser、SAXParserFactory
SAXParser:此类的实例可以用SAXParserFactory.newSAXParser()
方法得到。parse()
方法的第一个参数为xml路径,第二个参数为事件处理器,当把事件处理器传递进来,相当于在方法里面绑定了一个事件
SAXParserFactory:实例从newInstance()
方法得到 -
比如有以下xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>zhangsan</name>
<age>20</age>
</person>
程序执行到<person>
、<name>
等这种开始标签的时候,会自动调用startElement(String uri,String localName,String qName,Attributes attributes)
方法,该方法通过参数qName把标签名称返回,执行到文本zhangsan的时候自动调用characters(char[] ch,int start,int length)
方法,返回文本内容,执行到</name>
的时候自动调用endElement(String uri,String localName,String qName)
方法
使用jaxp的sax方式解析xml
sax方式只能实现查询操作,不能实现增删改操作
来个需求:打印整个xml文档内容
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
</p1>
<p1>
<name>lisi</name>
<age>30</age>
</p1>
</person>
public class classtest {
public static void main(String[] args) throws Exception {
/*
* 1、创建解析器工厂
* 2、创建解析器
* 3、 执行parse方法
* 4、需要自己创建一个类,来继承DefaultHandler
* 5、重写类里面的三个方法
*/
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); //创建解析器工厂
SAXParser saxParser=saxParserFactory.newSAXParser(); //创建解析器
saxParser.parse("src/1.xml", new MyDefault1()); //执行parse方法
}
}
class MyDefault1 extends DefaultHandler{
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
System.out.print("<"+qName+">");
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
System.out.print(new String(ch,start,length));
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
System.out.print("<"+qName+"/>");
}
}
再来个需求:打印所有name元素的值
public class classtest {
public static void main(String[] args) throws Exception {
/*
* 1、创建解析器工厂
* 2、创建解析器
* 3、 执行parse方法
* 4、需要自己创建一个类,来继承DefaultHandler
* 5、重写类里面的三个方法
*/
SAXParserFactory saxParserFactory=SAXParserFactory.newInstance(); //创建解析器工厂
SAXParser saxParser=saxParserFactory.newSAXParser(); //创建解析器
saxParser.parse("src/1.xml", new MyDefault2()); //执行parse方法
}
}
//实现获取所有name元素的值
class MyDefault2 extends DefaultHandler{
boolean flag=false;
@Override
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
// TODO Auto-generated method stub
super.startElement(uri, localName, qName, attributes);
//判断qName是否是name元素
if("name".equals(qName)) {
flag=true;
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
// TODO Auto-generated method stub
super.characters(ch, start, length);
//当flag值是true的时候,表示解析到name元素
if(flag==true) {
System.out.println(new String(ch,start,length));
}
}
@Override
public void endElement(String uri, String localName, String qName) throws SAXException {
// TODO Auto-generated method stub
super.endElement(uri, localName, qName);
//把flag设置成false,表示name元素结束
if("name".equals(qName)) {
flag=false;
}
}
}
解析器dom4j简介
-
dom4j不是javase的一部分,想要使用,需要导入dom4j提供的jar包。方法:创建一个文件夹lib,复制jar包到lib下面,右键点击lib,build path->add to build path(看到jar包变成奶瓶样子,即成功导入)
-
执行下面两行代码即可得到document文档
SAXReader reader=new SAXReader();
Document document=reader.read(url);
Document的父接口是Node,如果在Document里面找不到想要的方法,到Node里面去找
使用dom4j实现查询操作
来个需求:查询所有name元素里面的值
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1>
<name>zhangsan</name>
<age>20</age>
</p1>
<p1>
<name>lisi</name>
<age>30</age>
</p1>
</person>
public class classtest1 {
public static void main(String[] args) throws Exception {
/*
* 1、创建解析器 SAXReader reader=new SAXReader(); Document document=reader.read(url);
* 2、得到document Document document=reader.read(url);
* 3、得到根节点 getRootElement()
* 4、得到所有的p1
* element(qname),表示获取标签下面的第一个子标签,qname即标签的名称,如name
* elements(qname),获取标签下面是qname这个名称的所有子标签(一层)
* elements(),获取标签下面的一层子标签
* 5、得到name
* 6、得到name里面的值
*/
selectName();
}
//查询xml中所有name元素的值
public static void selectName() throws Exception{
SAXReader reader=new SAXReader(); //创建解析器
Document document=reader.read("src/1.xml"); //得到document
Element root=document.getRootElement(); //得到根节点
List<Element> list=root.elements("p1"); //得到p1
//若想得到第二个p1,可用句子:Element p2=list.get(1);
for(Element element:list) {
//element是每一个p1元素
//得到p1下面的name元素
Element name1=element.element("name");
//得到name里面的值
String s=name1.getText();
System.out.println(s);
}
}
}
使用dom4j实现添加操作
需求:在第一个p1下添加一个<sex>nv</sex>
//在第一个p1下添加一个<sex>nv</sex>
public static void addSex() throws Exception {
SAXReader reader=new SAXReader(); //创建解析器
Document document=reader.read("src/1.xml"); //得到document
Element root=document.getRootElement(); //得到根节点
Element p1=root.element("p1"); //得到第一个p1
Element sex1=p1.addElement("sex"); //直接添加sex
sex1.setText("nv"); //在sex下添加文本
//回写xml
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("src/1.xml"), format);
xmlWriter.write(document);
xmlWriter.close(); //关掉流
}
使用dom4j在特点位置添加节点
需求:在第一个p1下面的age之前添加一个school
//在第一个p1下面的age之前添加一个school
public static void addBeforeAge() throws Exception{
SAXReader reader=new SAXReader(); //创建解析器
Document document=reader.read("src/1.xml"); //得到document
Element root=document.getRootElement(); //得到根节点
Element p1=root.element("p1"); //得到第一个p1
List<Element> list=p1.elements(); //得到第一个p1下面的所有元素
Element school=DocumentHelper.createElement("school"); //创建要添加的元素
school.setText("ligong"); //创建文本
list.add(1, school); //在特定位置添加
//回写xml
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter xmlWriter=new XMLWriter(new FileOutputStream("src/1.xml"), format);
xmlWriter.write(document);
xmlWriter.close(); //关掉流
}
dom4j里面封装方法
下面封装获取document方法和回写方法:
//工具类
class Dom4jUtils{
public static Document getDocument(String path){
//返回document
try {
SAXReader reader=new SAXReader(); //创建解析器
Document document=reader.read(path); //得到document
return document;
}
catch(Exception e) {
e.printStackTrace();
}
return null;
}
public static void xmlWriters(String path,Document document) {
//回写xml
try {
OutputFormat format=OutputFormat.createPrettyPrint();
XMLWriter xmlWriter=new XMLWriter(new FileOutputStream(path), format);
xmlWriter.write(document);
xmlWriter.close(); //关掉流
}catch(Exception e) {
e.printStackTrace();
}
}
}
也可以把里面用到的xml文件的路径封装成一个常量,如:
public static final String PATH="src/1.xml";
使用dom4j实现修改节点
需求:修改第一个p1下的age元素的值为21
//修改第一个p1下的age元素的值为21
public static void chAge() throws Exception{
Document document=Dom4jUtils.getDocument("src/1.xml"); //用封装好的方法获取document
Element root=document.getRootElement(); //得到根节点
Element p1=root.element("p1"); //得到第一个p1
Element age=p1.element("age"); //得到第一个p1下的age
age.setText("21"); //修改age
Dom4jUtils.xmlWriters("src/1.xml", document); //用封装好的方法回写xml
}
使用dom4j实现删除节点操作
需求:删除第一个p1下面的school
//删除第一个p1下的school
public static void delSchool() throws Exception{
Document document=Dom4jUtils.getDocument("src/1.xml"); //用封装好的方法获取document
Element root=document.getRootElement(); //得到根节点
Element p1=root.element("p1"); //得到第一个p1
Element sch=p1.element("school"); //得到school
p1.remove(sch); //通过父节点删除
Dom4jUtils.xmlWriters("src/1.xml", document); //用封装好的方法回写xml
}
使用dom4j实现获取属性值的操作
需求:获取第一个p1里面属性id1的值
<?xml version="1.0" encoding="UTF-8"?>
<person>
<p1 id1="aaa">
<name>zhangsan</name>
<age>21</age>
<sex>nv</sex>
</p1>
<p1>
<name>lisi</name>
<age>30</age>
</p1>
</person>
//获取第一个p1里面属性id1的值
public static void getId() {
Document document=Dom4jUtils.getDocument("src/1.xml"); //用封装好的方法获取document
Element root=document.getRootElement(); //得到根节点
Element p1=root.element("p1"); //得到第一个p1
String id=p1.attributeValue("id1");
System.out.println(id);
}
XPATH的简介
学会看xpath文档
使用dom4j支持xpath操作
-
默认情况下,dom4j不支持xpath,如果想要在dom4j里面使用xpath,首先要引入支持xpath的jar包,把jar包导入到项目中
-
dom4j里面提供了两个方法,用来支持xpath:selectNodes(“xpath表达式”)获取多个节点;selectSingleNode(“xpath表达式”)获取一个节点
来个需求:使用xpath查询xml中所有name元素的值
public static void seName() throws Exception{
//查询xml中所有name元素的值
SAXReader reader=new SAXReader(); //创建解析器
Document document=reader.read("src/1.xml"); //得到document
List<Node> list=document.selectNodes("//name"); //使用方法得到所有name元素
//遍历list集合
for(Node node:list) {
String s=node.getText(); //node是每一个name元素,得到name元素里面的值
System.out.println(s);
}
}