简介
XML是一种可扩展标记性语言,标签名可自定义。
用途:html主要用于显示数据,xml主要用于存储数据
xml的文档声明
<?xml version="1.0" encoding="gbk" ?> gbk\utf-8
xml中的空格和换行都会被当成内容解析,需注意代码格式
注释<!--代码-->
转义字符(包含分号)
字符 | 书写形式 |
---|---|
& | &分号 |
< | <分号 |
/> | >分号 |
" | "分号 |
’ | '分号 |
CDTAT区
<![CDATA[代码]]>
CDATA区中的代码不需要另外进行转义
PI指令可以设置xml样式
<?xml-stylesheet type="text/css" href="css的路径" ?>
xml的约束
dtd约束和schema约束
dtd文件
- 复杂标签元素<!ELEMENT 元素名(子元素)>
子元素可以用 | 或,隔开
符号“|”仅出现其中一个元素
符号“,”元素需按顺序出现 - 简单标签元素<!ELEMENT 元素名 (#PCDATA)>
代码 | 代表内容 |
---|---|
(#PCDATA) | 字符串类型 |
EMPTY | 空 |
ANY | 任意 |
元素多次出现,元素名后加符号
符号 | 出现次数 |
---|---|
+ | 一次或多次 |
? | 零次或一次 |
* | 零次或多次 |
xml文件中引入dtd文件
<!DOCTYPE 根元素名称 SYSTEM "dtd文件路径">
<!DOCTYPE 根元素名称 [dtd代码] >
<!DOCTYPE 根元素名称 PUBLIC "dtd名称" "dtd文档的url">
约束属性
语法<!ATTLIST 元素名称 属性名称 属性类型 属性的约束>
属性类型
CDATA--------字符串
枚举-------------(aa|bb|cc)
属性约束
- #REQUIRED:属性必须存在
- #IMPLIED:属性可有可无
- #FIXED:属性的值为固定
- 直接值:有这个属性就是这个值,没这个属性
实体的定义
语法<!ENTITY 实体名称 “实体的值”>
举例:
<!ENTITY TEST "HAHAH">
使用实体 &实体名称; &TEST
schema约束
符合xml语法,一个xml中可以有多个schema,schema支持更多的数据类型。
<element name="根节点">
<complexType>
<sequence>
<element name="" type="" ></element>
<element name="" type="" ></element>
</sequence>
</complexType>
</element>
xml的解析
dom和sax解析
- dom在内存中分配树形结构,每部分都封装成对象,
优点:方便增删改操作
缺点:文件过大时,会造成内存溢出 - sax采用事件驱动,边读边解析,不会造成内存溢出
优点:不会造成内存溢出
缺点:不能实现增删改操作
使用jaxp实现查询节点操作
//创建解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//通过解析器工厂创建解析器
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//解析器解析目标xml文件
Document document = documentBuilder.parse("src/1.xml");
//document文件获取标签为name的列表
NodeList list = document.getElementsByTagName("name");
//遍历list列表,输出文本内容
for (int i = 0; i < list.getLength(); i++) {
System.out.println(list.item(i).getTextContent());
}
使用jaxp实现添加节点操作
//创建解析器工厂
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
//通过解析器工厂创建解析器
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
//解析器解析目标xml文件
Document document = documentBuilder.parse("src/1.xml");
//得到根节点
NodeList list = document.getElementsByTagName("p1");
Node p1 = list.item(0);
//创建新的元素并添加内容
Element sexElement = document.createElement("sex");
sexElement.setTextContent("nv");
//通过父节点加到末尾
p1.appendChild(sexElement);
//回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
使用jaxp实现修改节点操作
//创建解析器
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse("src/1.xml");
//得到节点并修改
NodeList list = document.getElementsByTagName("sex");
list.item(0).setTextContent("nn");
//回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
使用jaxp实现删除节点操作
//创建解析器
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
Document document = documentBuilder.parse("src/1.xml");
//获取父节点后使用removeChild删除子节点
NodeList list = document.getElementsByTagName("sex");
Node childNode = list.item(0);
Node parentNode = childNode.getParentNode();
parentNode.removeChild(childNode);
//回写xml
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(new DOMSource(document), new StreamResult("src/1.xml"));
使用jaxp实现遍历节点操作
递归
//创建解析器
//调用递归方法
listElement(document);
//回写xml
//递归方法
private static void listElement(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++) {
listElement(list.item(i));
}
}
sax解析
边读边解析
- 解析到标签时,自动执行startElement(…String qName…)方法,qName为标签名称
- 解析到文本时,自动执行characters(char[] ch,int start, int length)方法,new String (ch,start,length)为标签文本内容
- 解析到结束标签时,自动执行endElement(…String qName…)方法,qNmae为标签名称
使用jaxp的sax方式操作xml
dom4j
需要导包dom4j.jar
//xml文件
<person>
<p1>
<name></name>
<age></age>
</p1>
</person>
使用dom4j实现查询xml操作
//创建解析器,得到document
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("src/1.xml");
//一次获取节点
//root(parent)---p1---name
Element root = document.getRootElement();
Element p1Element = root.element("p1");
Element nameElement = p1Element.element("name");
System.out.println(nameElement.getText());
使用dom4j实现在末尾添加节点的操作
//创建解析器,得到document
SAXReader saxReader = new SAXReader();
Document document = saxReader.read("src/1.xml");
Element root = document.getRootElement();
Element p1Elements = root.element("p1");
//添加元素,设置内容
Element aaElement = p1Elements.addElement("aa");
aaElement.setText("bb");
//回写xml
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter xmlWriter = new XMLWriter(new FileOutputStream("src/1.xml"), format);
xmlWriter.write(document);
xmlWriter.close();
使用dom4j实现在特定位置添加节点的操作
...创建解析器...
//得到根节点
Element root = document.getRootElement();
Element p1Elements = root.element("p1");
//得到要添加位置的父元素列表
List<Element> pList = p1Elements.elements();
//创建新元素
Element aaElement = DocumentHelper.createElement("aa");
aaElement.setText("cc");
//指定位置加入元素
pList.add(1, aaElement);
...回写...
使用dom4j实现修改的操作
ageElement.setText("33");
使用dom4j实现删除的操作
p1Element.remove(ageElement);
dom4j对XPath的支持
- /AAA/DDD/BBB:AAA下的DDD下的BBB
- //BBB:所有名称为BBB的元素
- /*:所有元素
- BBB[1]:第一个BBB元素
- BBB[last()]:最后一个BBB元素
- //BBB[@id]:有id属性的BBB元素
- //BBB[@id=‘aa’]:属性为id,值为aa的BBB元素
提供的方法 - selectNodes(“xpath表达式”) 获取多个节点
- selectSingleNode(“xpath表达式”) 获取一个节点