XML的介绍及使用DOM,DOM4J解析xml文件

1 XML简介

XML(可扩展标记语言,Extensible Markup Language)是一种用于定义文档结构和数据存储的标记语言。它主要用于在不同的系统之间传输和存储数据。

作用:

  • 数据交互配
  • 置应用程序和网站
  • Ajax基石

特点

  • XML与操作系统、编程语言的开发平台无关
  • 实现不同系统之间的数据交换

2 XML文档结构

<?xml version="1.0" encoding="UTF-8"?>
<books>
  <!--图书信息 -->
  <book id="bk101">
    <author>王珊</author>
    <title>.NET高级编程</title>
    <description>包含C#框架和网络编程等</description>
  </book>
  <book id="bk102">
    <author>李明明</author>
    <title>XML基础编程</title>
    <description>包含XML基础概念和基本作用</description>
  </book>
</books>

2.1 XML标签

<元素名 属性名=“属性值”>元素内容</元素名>

  • 属性值用双引号包裹
  • 一个元素可以有多个属性
  • 属性值中不能直接包含<、“、&
  • 不建议使用的字符:‘、>

2.2 注意事项

  • 所有XML元素都必须有结束标签
  • XML标签对大小写敏感
  • XML必须正确的嵌套
  • 同级标签以缩进对齐
  • 元素名称可以包含字母、数字或其他的字符
  • 元素名称不能以数字或者标点符号开始
  • 元素名称中不能含空格

3 解析XML技术

DOM:

  • 基于XML文档树结构的解析
  • 适用于多次访问的XML文档
  • 特点:比较消耗资源

SAX:

  • 基于事件的解析
  • 适用于大数据量的XML文档
  • 特点:占用资源少,内存消耗小

DOM4:

  • J非常优秀的Java XML API
  • 性能优异、功能强大
  • 开放源代码

3.1 DOM的介绍

文档对象模型(Document Object Model),DOM把XML文档映射成一个倒挂的树

<book >
    <title>三国演义</title>
    <author>罗贯中</author>
    <price>30元</price>
</book>

3.2 DOM常用接口介绍

4 使用DOM来解析XML1

4.1 通常解析的步骤

DOM解析XML文件步骤:

1.创建解析器工厂对象

2.解析器工厂对象创建解析器对象

3.解析器对象指定XML文件创建Document对象

4.以Document对象为起点操作DOM树

5.创建Transformer对象

作用->将内存中的document对象写入xml文件

1)TransformerFactory.newInstance() 获取TransformerFactory()对象

2)transformerFactory.newTransformer() 获取Transformer对象

3)transformer.transform() 将document写入xml文件

4.2显示“收藏信息.xml”

显示“收藏信息.xml”文件中收藏的手机品牌和型号

<?xml version="1.0" encoding="GB2312"?>
<PhoneInfo>
    <Brand name="华为">
        <Type name="U8650"/>
        <Type name="HW123"/>
        <Type name="HW321"/>
    </Brand>
    <Brand name="苹果">
        <Type name="iPhone4"/>
    </Brand>
</PhoneInfo>
package practise.practise02;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

public class DomShowPhone {
    public static void main(String[] args) {

        try {
            // 1. 创建一个 DocumentBuilderFactory 实例
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

            // 2. 使用工厂方法创建一个 DocumentBuilder 实例
            DocumentBuilder builder = factory.newDocumentBuilder();

            // 3. 解析 XML 文件并获取 DOM Document 对象
            Document document = builder.parse("Test10/config/phone.xml");

            // 4. 规范化 XML 文档
            document.getDocumentElement().normalize();//除去多余的换行符和空格,使树形结构更加完整

            // 5. 获取根元素
            //            Element root = document.getDocumentElement();//获取根元素
            //            System.out.println("根元素为: " + root.getNodeName());//获取根元素名字

            // 6. 获取所有 <Brand> 元素
            NodeList nList = document.getElementsByTagName("Brand");//按照文档顺序将所有Brand元素返回到集合中

            for (int temp = 0; temp < nList.getLength(); temp++) {
                Node node = nList.item(temp);//遍历获取Brand节点
                Element eElement= (Element) node;
                System.out.println("品牌:"+eElement.getAttribute("name"));//得到name属性的值
                NodeList type = eElement.getElementsByTagName("Type");

                for (int i = 0; i < type.getLength(); i++) {
                    Element type1 = (Element) type.item(i);
                    type1.setAttribute("id","type"+(i+1));
                    System.out.println("型号:"+type1.getAttribute("name"));//获取name属性的值    Attribute属性的意思
                }

                //                if (node.getNodeType() == Node.ELEMENT_NODE) {//用于确保当前节点是一个元素节点(ELEMENT_NODE)。
                //                    Element eElement = (Element) node;
                //
                //                    // 打印书籍的详细信息
                //                    System.out.println("Title: " + eElement.getElementsByTagName("title").item(0).getTextContent());//获取元素的文本内容
                //                    System.out.println("Author: " + eElement.getElementsByTagName("author").item(0).getTextContent());
                //                    System.out.println("Price: " + eElement.getElementsByTagName("price").item(0).getTextContent());
                //                }
            }
            Node brand = nList.item(0);
            Element brand1 = (Element) brand;
            brand1.setAttribute("id","brand1");
            //            brand1.setAttribute("id","b1");

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

4.3 收藏信息保存到文件中

package practise.practise03;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

public class AddBrandDOM {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse("Test10/config/phone.xml");
            Element newBrand = document.createElement("Brand");
            newBrand.setAttribute("name","三星");
            Element newType = document.createElement("Type");// tag 是标签的意思
            newType.setAttribute("name","Note4");
            newBrand.appendChild(newType);//将newType元素添加到newBrand的子节点
            Element root = document.getDocumentElement();//得到根节点
            root.appendChild(newBrand);//将newBrand元素添加到根元素的子节点

            // 6. 创建 Transformer 对象以保存修改后的 DOM 树
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            // 7. 设置输出属性
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");

            // 8. 创建 DOMSource 对象
            DOMSource domSource = new DOMSource(document);

            // 9. 创建 StreamResult 对象并指定输出文件
            StreamResult streamResult = new StreamResult("Test10/config/phone.xml");

            // 10. 保存修改后的 XML 到指定文件
            transformer.transform(domSource, streamResult);

            System.out.println("XML 文件已成功修改");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

4.4 修改删除手机收藏

修改/删除DOM节点:

  • 给所有的Brand标签添加id属性
  • 获取Brand标签
  • 调用setAttribute()方法添加属性

删除Brand值为“华为”的标签

  • getElementsByTagName()方法获取Brand标签列表
  • 获得Brand值为“华为”的标签对象
  • 通过getParentNode()方法获得父节点对象
  • 调用父节点的removeChild()方法删除节点

XML文件:

<PhoneInfo>
  <Brand name="苹果">
    <Type name="iPhone4"/>
  </Brand>
  <Brand name="华为">
    <Type name="U8650"/>
    <Type name="HW123"/>
    <Type name="HW321"/>
  </Brand>
  <Brand id="brand2" name="三星"> 
    <Type name="Note4"/> 
  </Brand>  
  <price id="3" name="小米"> 
    <Type name="小米11"/> 
  </price>
</PhoneInfo>
package practise.practise1;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import java.io.IOException;

public class RomeBrandDOM {
    public static void main(String[] args) {
        try {
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.parse("Test11/config/phone.xml");
            Element root = document.getDocumentElement();//获取根节点元素
            root.normalize();
            NodeList nodeList = document.getElementsByTagName("Brand");
            for (int i = 0; i < nodeList.getLength(); i++) {
                document.getDocumentElement().normalize();
                Node node=nodeList.item(i);
                Element element = (Element) node;
                element.setAttribute("id","brand"+(i+1));
                if ("华为".equals(element.getAttribute("name"))){
                    element.getParentNode().removeChild(element);
                    i--;
                }
            }
            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();

            // 7. 设置输出属性
            transformer.setOutputProperty(OutputKeys.INDENT, "yes"); // 启用缩进
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4"); // 设置缩进量(每级缩进4个空格)
            transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8"); // 设置编码
            transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); // 保留 XML 声明
            transformer.setOutputProperty(OutputKeys.STANDALONE, "yes");

            // 8. 创建 DOMSource 对象
            DOMSource domSource = new DOMSource(document);

            // 9. 创建 StreamResult 对象并指定输出文件
            StreamResult streamResult = new StreamResult("Test11/config/phone.xml");

            // 10. 保存修改后的 XML 到指定文件
            transformer.transform(domSource, streamResult);

            System.out.println("XML 文件已成功修改");

        } catch (ParserConfigurationException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

5 使用DOM4J解析XML

5.1 Dom4j主要内容简述:

  • Document 文档 - 代表整个 XML 文档。 Document 对象通常称为 DOM 树。
  • Element 元素 - 表示 XML 元素。元素对象具有操作其子元素、文本、属性和命名空间的方法。
  • Attribute 属性 - 表示元素的属性。属性具有获取和设置属性值的方法。它具有父类型和属性类型。
  • Node 节点 - 表示元素、属性或处理指令

5.2 常见的Dom4j方法描述

  • SAXReader.read(xmlSource)() − 从 XML 源构建 DOM4J 文档。
  • Document.getRootElement() − 获取 XML 文档的根元素。
  • Element.node(index) − 获取元素中特定索引处的 XML 节点。
  • Element.attributes() − 获取元素的所有属性。
  • Node.valueOf(@Name) − 获取具有给定元素名称的属性值

5.3 Dom4J的XML解析器

SAXReader解析器:

SAXReader reader = new SAXReader();
String xmlString = ResourceUtil.readStr("conversion/TestMain.xml", StandardCharsets.UTF_8);
Document document = reader.read(new ByteArrayInputStream(xmlString.getBytes(StandardCharsets.UTF_8)));

5.4 使用DOM4J解析XML文件示例

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PhoneInfo>
  <Brand id="brand1" name="苹果">
    <Type name="iPhone4"/>
  </Brand>

  <Brand id="brand2" name="三星"> 
    <Type name="Note4"/> 
  </Brand>  
  <price id="3" name="小米"> 
    <Type name="小米11"/> 
  </price>
</PhoneInfo>
  • 显示手机收藏信息
  • 保存手机收藏信息
  • 为手机收藏信息添加新的节点
  • 修改/删除手机收藏信息节点
package practise.practise2;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;

import java.io.FileOutputStream;
import java.util.Iterator;
import java.util.List;

@SuppressWarnings("all")
public class ShowDom4j {
    public static void main(String[] args) {
        String str="Test11/config/phone.xml";
        SAXReader saxReader = new SAXReader();
        try {
            //1 显示手机收藏信息
            Document document = saxReader.read(str);
            Element rootElement = document.getRootElement();
            List<Element> brandList = rootElement.elements("Brand");//取得子节点所有Brand元素
            Iterator<Element> iterator = brandList.iterator();
            while (iterator.hasNext()) {
                Element brandElement = iterator.next();
                System.out.print("Brand-id="+brandElement.attributeValue("id")+",Brand-name="+brandElement.attributeValue("name"));
                List<Element> type = brandElement.elements("Type");
                for (Element element :type) {
                    System.out.println("Type-name="+element.attributeValue("name"));
                }
            }
            //2,3 为手机收藏信息并添加新节点并保存
            Element priceElement = rootElement.addElement("price");
            priceElement.addAttribute("id","brand3");
            priceElement.addAttribute("name","小米");
            Element typeElement = priceElement.addElement("Type");
            typeElement.addAttribute("name","小米11");

            //4 修改/删除手机收藏信息节点  删除苹果节点的子节点
            Node node = document.selectSingleNode("//Brand[@name='苹果']");//xpath 语法
            Element branElment=(Element) node;
            rootElement.remove(branElment);

            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("UTF-8"); // 设置编码
            format.setIndent(true); // 启用缩进
            format.setIndentSize(4); // 设置缩进的空格数
            format.setNewLineAfterDeclaration(true); // 在 XML 声明后添加换行
            XMLWriter xmlWriter = new XMLWriter(new FileOutputStream(str),format);
            xmlWriter.write(document);
            System.out.println("写入成功xml!!");
            xmlWriter.close();


        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  • 18
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值