<?xml version="1.0" encoding="UTF-8"?>
<!--
xml:是一个可扩展的标记语言
01.很像超文本标记语言(html)
02.xml文件着重保存或者传输数据,不专注显示
03.无需预编译
04.符合w3c标准
< : <
> : >
" : "
' : '
& : &
<![CDATA[代码]]>
CDATA: character data 字符数据
不会被解析器解析的文本!在CDATA标签中定义的代码 不会被当作标记!
PCDATA: parsed character data 被解析的字符数据
-->
<students>
<student id="001" name="小黑黑" score=">80">我是小黑黑</student>
<student id="002" name="大黑黑" score="<80">我是大黑黑</student>
</students>
<![CDATA[ "" ;; '' <><>< ]]>
第一个xml文件
/**
什么是标记??? 计算机所能理解的一种信息符号!我们之前定义的变量,java中的基本数据类型=====理解成标记!
xml:是一种可扩展的标记语言!
01.专注于保存数据,传输!不是显示数据!
02.xml文件中的标签没有被定义,我们可以自定义标签名称!
<student name="admin"></student>
<学生 姓名="小白"></学生>
03.自我描述性
04.符合W3C标准的!
Dom: 文档对象模型(Document Object Model):dom把xml文件映射成倒挂的树
解析xml的4中解析器!
Dom:基于xml文档树结构的解析!把文件的内容读取到内存中,比较占内存!消耗资源
SAX:基于事件的解析!不需要将数据存储在内存中!占用资源少!
JDom:第一个java特定模型! 2 8原则!本身不包含解析器!使用SAX2解析器来解析xml文件!
Dom4j:是Jdom的一个分支!分享源代码! 性能优异!功能强大!
<student age="50">小黑</student>
student:元素名
age:属性名
50:属性值
小黑:元素内容
特殊字符:
< <
> >
& &
' '
" "
CDATA:不被xml解析器解析!
<![CDATA[内容]]>
*/
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE school[ //声明这是一个 school类型的文档
<!ELEMENT school(teacher)> //根节点是 school 下面只能有teacher
<!ELEMENT teacher(student+)> //teacher可以有至少一个student节点
<!ELEMENT teacher(student*)> //teacher可以有多个,也可以没有
<!ELEMENT teacher(student?)> //teacher可以有1个,也可以没有
<!ATTLIST teacher //定义teacher节点中可以有的属性
ID CDATA #REQUIRED // #REQUIRED 属性值是 必须的 #IMPLIED 属性值不是必须的 EMPTY 空的
name CDATA "false">
]>
创建一个dtd文件
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入外部的dtd文档 -->
<!DOCTYPE school SYSTEM"my.dtd">
创建一个xml引入dtd文件
=====================DOM解析xml文件=================================
<?xml version="1.0" encoding="UTF-8"?>
<PhoneInfo>
<Brand name="华为">
<Type name="P9"/>
</Brand>
<Brand name="苹果">
<Type name="Iphone6"/>
<Type name="Iphone7"/>
</Brand>
</PhoneInfo>
public class DomXml {
//声明文档树
static Document document=null;
/**
* 使用Dom解析xml文件
*/
public static void main(String[] args) {
getDom();
delPhone();
}
/**
* 获取dom树
*/
public static void getDom(){
try {
//01.创建解析器工厂
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
//02.创建解析器
DocumentBuilder builder = factory.newDocumentBuilder();
//03.指定需要解析的xml文件 获得整个dom树
document = builder.parse("收藏信息.xml");
//04.获取xml文件的根节点
NodeList list = document.getElementsByTagName("Brand");
System.out.println("有几个Brand节点:"+list.getLength());
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
Element element= (Element) node;
System.out.println("手机名称===》"+element.getAttribute("name"));
//怎么获取手机下面的品牌信息
NodeList cList = element.getChildNodes();
for (int j = 0; j < cList.getLength(); j++) {
Node cNode = cList.item(j);
//先判断cNode是否是一个元素节点
if (cNode.getNodeType()==Node.ELEMENT_NODE) {
Element cElement= (Element) cNode;
System.out.println("手机品牌===》"+cElement.getAttribute("name"));
}
}
}
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//把内存中的数据 保存在xml中
public static void saveXml() {
try {
//???怎么把内存中的 节点 保存到xml中
//01.创建转换器工厂
TransformerFactory factory = TransformerFactory.newInstance();
//02.创建转换器对象
Transformer former = factory.newTransformer();
//这是我们输出格式
former.setOutputProperty("indent", "yes");
//03.从内存中 输出到 xml文件 输出流
DOMSource source=new DOMSource(document);
StreamResult result=new StreamResult(new OutputStreamWriter
(new FileOutputStream("收藏信息.xml"), "utf-8"));
former.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
}
/**
* 新增手机信息
*/
public static void addPhone(){
//在内存中首先 创建我们需要增加的 节点
Element element = document.createElement("Brand");
//增加属性
element.setAttribute("name", "金立");
//再创建一个节点 只有文档树可以创建节点
Element elementType = document.createElement("Type");
elementType.setAttribute("name", "金立555");
//把type节点放入Brand中
element.appendChild(elementType);
//获取根节点
document.getElementsByTagName("PhoneInfo").item(0).appendChild(element);
//以上的操作 全都是在 内存中! 并没有真正的保存到xml文件中
saveXml(); //shift +alt +M 选中的区域提取成方法
}
/**
* 修改手机信息
*/
public static void updatePhone(){
//获取需要修改的节点
NodeList list = document.getElementsByTagName("Brand");
//循环操作
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
Element element=(Element) node;
if (element.getAttribute("name").equals("金立")) {
element.setAttribute("name", "三星");
}
}
//把内存中修改的数据 保存到xml
saveXml();
}
/**
* 删除指定的手机信息
*/
public static void delPhone(){
//获取需要修改的节点
NodeList list = document.getElementsByTagName("Brand");
//循环操作
for (int i = 0; i < list.getLength(); i++) {
Node node = list.item(i);
Element element=(Element) node;
if (element.getAttribute("name").equals("三星")) {
element.getParentNode().removeChild(element);
}
}
//把内存中删除的数据 保存到xml
saveXml();
}
}
public class Dom4jTest { // Dom4j解析xml
// 因为所有的方法都需要Dom树
static Document document = null;
static Element root = null;
public static void main(String[] args) {
// 获取dom树
getDocument();
// addPhone();
deletePhone();
updatePhone();
showPhone();
}
// 解析xml文件
public static void getDocument() {
SAXReader reader = new SAXReader();
try {
document = reader.read("收藏信息.xml");
root = document.getRootElement();// 获取根节点
} catch (DocumentException e) {
e.printStackTrace();
}
}
/**
* 显示所有的手机信息
*/
public static void showPhone() {
// 遍历所有的节点
Iterator itBrand = root.elementIterator();
while (itBrand.hasNext()) {
Element brand = (Element) itBrand.next();
System.out.println("手机的品牌是:" + brand.attributeValue("name"));
System.out.println("手机的编号是:" + brand.attributeValue("id"));
System.out.println("===========下面是子节点============");
Iterator itType = brand.elementIterator();
while (itType.hasNext()) {// 获取手机型号
Element type = (Element) itType.next();
System.out.println("手机的型号是:" + type.attributeValue("name"));
// 输出文本节点的值
if (!type.getText().equals("")) {
System.out.println(type.getTextTrim());
}
}
}
}
// 保存xml信息
public static void save(String path) {
OutputFormat format = null;
XMLWriter writer = null;
try {
// dom4j的转换器 不用使用 new createPrettyPrint底层有 new
format = OutputFormat.createPrettyPrint();
// 写入xml文件
writer = new XMLWriter(new FileWriter(path), format);
writer.write(document);
} catch (IOException e) {
e.printStackTrace();
} finally {
// 关流
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 新增节点
public static void addPhone() {
Element element = root.addElement("Brand");
// 节点设置属性
element.addAttribute("name", "黑莓");
// 节点下面新增子节点
Element type = element.addElement("Type");
type.addAttribute("name", "A1");
// 保存 省略 我们 节点之间的拼接! dom需要拼接
save("收藏信息.xml");
}
// 删除
public static void deletePhone() {
// 获取所有Brand
Iterator brand = root.elementIterator();
while (brand.hasNext()) {
Element element = (Element) brand.next(); // 拿到每一个Brand
// 获取属性值 判断是不是 要删除的对象
if (element.attributeValue("name").equals("黑莓")) {
element.getParent().remove(element);
}
}
save("收藏信息.xml");
}
// 修改
public static void updatePhone() {
// 获取所有Brand
Iterator brand = root.elementIterator();
while (brand.hasNext()) {
Element element = (Element) brand.next(); // 拿到每一个Brand
// 获取属性值 判断是不是 要修改的对象
if (element.attributeValue("name").equals("哇哈哈")) {
element.attribute("name").setValue("哇哈哈哈哈");
}
}
save("收藏信息.xml");
}
}
使用dom4j解析 需要引入需要的jar包
覆盖xml文件
public class ParseXml {
public static void main(String[] args) throws IOException {
saveXml("user.xml");
}
/**
*
* @param path 需要覆盖的xml文件
* @throws IOException
*/
public static void saveXml(String path) throws IOException{
Document document=DocumentHelper.createDocument(); //创建一个dom对象
//给dom增加根节点
Element students = document.addElement("Students");
//在根节点下面增加 子节点
Element student = students.addElement("Student");
//给子节点增加属性
student.addAttribute("name","小黑");
//创建转换器工厂
OutputFormat format = OutputFormat.createPrettyPrint();
//设置编码格式
format.setEncoding("utf-8");
XMLWriter writer=new XMLWriter(new FileWriter(path), format);
//写入xml文件
writer.write(document);
//关闭流
writer.close();
}
}
作者:Rick__想太多先森