【深入浅出XML】包装纯粹信息的标记语言

news2024/12/26 22:39:18

XML

  • XML的定义和概述
    • 🎶XML的定义
    • 🎶XML的最好描述
    • 🎶HTML和XML的重要区别
    • 🎶XML的文档结构
    • 🎶其他一些标记
  • XML和优势
    • 🎶XML的优势
  • XML解析
    • 🎶DOM解析
      • ❔解析测试
        • 🤞解析步骤
        • 🤞案例测试
    • 🎶SAX解析
    • 🎶DOM4J解析
      • ❔解析步骤

XML的定义和概述

🎶XML的定义

XMLExtensible Makeup Language的缩写,是指可拓展性标记语言,用来传输和存储数据的一种标记语言。类似于HTML,XML弥补了HTML不能指定文档结构的不足XML被设计为具有自我描述性,其宗旨是传输数据。HTMLXML同宗同源于SGML(标准通用标记语言)。

🎶XML的最好描述

独立于软件和硬件的信息传输工具。

🎶HTML和XML的重要区别

  • XML被设计来传输和存储数据,焦点是数据的内容,而HTML被设计来显示数据,焦点是数据的外观。
  • XML中区分大小写。例如:<setting>和<Setting>是不同的标签
  • XML中的结束标志是绝对不能省略的,即使是没有结束标签也要以'/'结尾。
  • XML中属性值必须要用引号括起来,单引号双引号都行。
  • XML中属性名不能没有值。例如:HTML中<input type="text" name="username" checked />在XML中是不合法的。
  • XML可以自定义标签和文档结构。

🎶XML的文档结构

第一步:使用文档头,文档头是可选的,但强烈建议使用。
<?xml version="1.0" ?><?xml version="1.0" encoding="UTF-8" ?>
第二步:使用 文档类型定义(Document Type Definition),用来确保文档正确的一个重要机制,非必须。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration...>
<configuration>
...
</configuration>
第三步:写出根节点,即其内部内容(子节点,内容,属性...)元素的属性值一般是对元素内容的解释。

🎶其他一些标记

  • 处理指令,是那些专门在处理XML文档的应用程序中使用的指令,它们由<?和?>来限定其界限。
<?xml-stylesheet href="mystyle.css" type="text/css"?>
  • 实体引用,使用实体引用代替一些字符是一种好习惯。

在这里插入图片描述

XML和优势

🎶XML的优势

1. 解决了属性文件的局限性,属性文件是一种平面表结构,而XML可以表示层次结构;
// 属性文件内容
title.fontname=hhh
title.fontsize=12
menu.item.1=x
menu.item.2=y
// 对应的XML文件内容
<configuration>
	<title>
		<font>
			<name>hhh</name>
			<size>12</size>
		</font>
	</title>
	<menu>
		<item>x</item>
		<item>y</item>
	</menu>
</configuration>

XML解析

🎶DOM解析

DOM解析器可以把 xml 文档转换成树结构,对其树结构上的各个元素进行读取。
DOM解析器的接口已被W3C标准化了,org.w3c.dom包中包含了这些接口的定义。(Document、Element等)。

这是各个子接口的层次结构:

在这里插入图片描述

❔解析测试

🤞解析步骤

  1. 导入dom依赖(本地库没有,可以去中央仓库找找)

在这里插入图片描述

  1. 读入一个XML文档,需要一个DocumentBuilder对象。
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
  1. 然后开始读入文档(可以是File、URL或者某输入流)
// File(项目根路径)
Document doc = builder.parse(new File("src/main/....");

// InputStream (类的根路径)
Document doc = builder.parse(ClassLoader.getSystemClassLoader().getResourceAsStream(...);
  1. 开始解析

一些解析可用的方法:

Document接口
Element getDocumentElement() 返回文档的根元素。
Element接口:
String getTagName() 返回元素名字
String getAttribute(String name) 返回给定名字的属性值,没有该属性是返回空字符串。
Node接口
NodeList getChildNodes() 返回包含该节点所有子元素的节点列表
Node getFirstChild()
Node getLastChild()
CharacterData接口:
String getData() 返回存储在节点中的文本。返回的是一个CharacterDataText存在继承关系,而CharacterData继承于Node,一般取文本内容,是将Node向下转型为Text,再去getData()获取文本内容。
NodeList接口
int getLength() 返回列表中的节点数
Node item(int index) 返回索引值处的节点

🤞案例测试

一、创建个xml文件,下面是文件内容:

在这里插入图片描述

二、预期把这些信息都解析成Javabean Stu对象,下面是Stu类中的代码:

import java.util.Objects;
public class Stu {
    private String name;
    private String sex;
    private int age;

    public Stu(){}

    public Stu(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Stu{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        Stu stu = (Stu) o;
        return age == stu.age && Objects.equals(name, stu.name) && Objects.equals(sex, stu.sex);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, sex, age);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

三、通过上面认识到的接口方法,对该xml文件进行解析:

import org.ncpowernode.xml.bean.Stu;
import org.w3c.dom.*;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class XmlParseStu {
    private static File f = new File("src/main/resources/stu.xml");
    private static InputStream in = ClassLoader.getSystemClassLoader().getResourceAsStream("stu.xml");
    private static List<Stu> stuList = new ArrayList<>();
    public static void main(String[] args)
            throws ParserConfigurationException, IOException, SAXException {


        DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
        Document stuDocument = documentBuilder.parse(in);
        Element beginRoot = stuDocument.getDocumentElement();
        NodeList childNodes = beginRoot.getChildNodes();
        List<Element> nodeList = new ArrayList<>();

        // 将student 节点元素存入到nodelist集合中
        for(int i=0;i<childNodes.getLength();++i){
            Node node = childNodes.item(i);
            if (node instanceof Element) {
                Element element = (Element) node;
                nodeList.add(element);
            }
        }

        //nodeList.stream().forEach(node->System.out.println(node.getNodeName()));
        nodeList.stream()
                .forEach(element -> {
                    NodeList childs = element.getChildNodes();
                    String name="";
                    String sex="";
                    int age=0;
                    for(int i=0;i<childs.getLength();++i){
                        Node item = childs.item(i);
                        if (item instanceof Element) {
                             Element e = (Element)item;
                            Text text = (Text)item.getFirstChild();
                            String data = text.getData().trim();
                            String tagName = e.getTagName();
                            if(tagName.equals("name")){
                                name = data;
                            }else if(tagName.equals("sex")){
                                sex = data;
                            }else if(tagName.equals("age")){
                                age = Integer.parseInt(data);
                            }
                        }
                    }
                    Stu stu = new Stu(name,sex,age);
                    System.out.println(stu);
                });

    }
}

输出结果:

在这里插入图片描述
注意:这是自编题自解答,同一问题这个一步一步写的不一定是一最好的解析代码。DOM解析xml不适合元素很多的文档,那样parse成树后会占用很大内存。

🎶SAX解析

	SAX解析适合解析较大的xml文档,它是以流的形式进行解析,以开始标签与结束标签作为标志,遇到结束标签后,
执行结束对应的方法后,该元素就会在内存中被清除,不像DOM一样,解析成树结构存放于内存中随时可以访问。

Tomcat服务器中用到的Digester事件驱动型工具,即是对SAX事件驱动型XML处理工具,已包含到J2SE基础类库当中)的高层次的封装,针对SAX事件提供了更加友好的接口。

缺点:只能读文档,不可写。

🎶DOM4J解析

❔解析步骤

  • 一、获取Document 对象(有三种获取方法):
  1. 创建解析器对象,对XML 文件进行解析,获取Document对象:
SAXReader saxReader = new SAXReader();
Document testDoc = saxReader.read(ClassLoader.getSystemResource("test.xml"));
  1. 通过DocumentHelper 主动去创建Document 对象:
Document document = DocumentHelper.createDocument();
Element test = document.addElement("test");
  1. 通过DocumentHelper 去解析文本字符串获取Document 对象:
String text = "<test></test>";
Document textDoc = DocumentHelper.parseText(text);
  • 二、通过Document 对象获取标签/元素信息,从而进行解析。(大部分读操作都是和DOM一致的)

      一、节点对象操作方法
    
1. 获取文档的根节点
Element root = document.getRootElement();
2. 获取节点的文本
String text = node.getText();
String textTrim = node.getTextTrim();
3. 获取子节点集
List<Element> nodeList = node.elements("csdn");// 获取名为csdn的子节点的所有子节点
4. 在某个节点下添加节点
Element csdn = node.addElement("csdn");
5. 设置节点文本
csdn.setText("假正经的小柴");
6. 删除某个节点
parendNode.remove(childNode);
	二、节点对象属性的方法操作
1.取得某节点下的某属性
Attribute attribute = node.attribute("属性名");
2.设置属性值或者添加某属性值
node.setAttribute(String name,String value);
3.移除某属性值
node.remove(attribute);
4.获取所有属性
NamedNodeMap attributes = node.getAttributes();
5.获取属性的文本
String text = attribute.getText();
6.添加某属性
node.addAttribute(String name,String value);
7.获取所有属性
List<Attribute> attributes = node.attributes();
	三、将文档写入XML文件
1.文档中全为英文,不设置编码,直接写入的形式.  
       XMLWriter writer = new XMLWriter(new  FileWriter("ot.xml")); 
       writer.write(document);  
       writer.close();
    2.文档中含有中文,设置编码格式写入的形式.
       OutputFormat format = OutputFormat.createPrettyPrint();// 创建文件输出的时候,自动缩进的格式                  
       format.setEncoding("UTF-8");//设置编码
       XMLWriter writer = new XMLWriter(newFileWriter("output.xml"),format);
       writer.write(document);
       writer.close();
	四、字符串和XML的互换
1.将字符串转化为XML
      String text = "<csdn> <java>Java班</java></csdn>";
      Document document = DocumentHelper.parseText(text);
    2.将文档或节点的XML转化为字符串.
       SAXReader reader = new SAXReader();
       Document   document = reader.read(new File("csdn.xml"));            
       Element root=document.getRootElement();    
       String docXmlText=document.asXML();
       String rootXmlText=root.asXML();
       Element memberElm=root.element("csdn");
       String memberXmlText=memberElm.asXML();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/165402.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

在Windows部署Java的Jar包

背景 使用 Java 编写了一些有用的工具&#xff0c;因为不方便部署到服务器上&#xff0c;所以需要把 Java 生成的 jar 包在本地 Windows 上部署。 查阅了几种部署方式&#xff0c;认为通过 winsw 进行部署最方便。 安装 winsw 进入 winsw 的下载页面&#xff0c;下载 sampl…

【ROS2 入门】ROS 2 参数服务器(parameters)概述

大家好&#xff0c;我是虎哥&#xff0c;从今天开始&#xff0c;我将花一段时间&#xff0c;开始将自己从ROS1切换到ROS2&#xff0c;在上一篇中&#xff0c;我们一起了解ROS 2中Topic&#xff0c; 这一篇&#xff0c;我们主要会围绕ROS中另外一个重要的概念“Parameters ”&am…

图的拓扑排序(AOV网络)

文章目录拓扑排序概念实现邻接表(队列)邻接矩阵(栈)总结源代码邻接表邻接矩阵拓扑排序 概念 拓扑排序是对有向无环图的顶点的一种排序. AOV网络 : 在有向图中, 用顶点表示活动或者任务, 弧表示活动或者任务间的优先关系, 则此有向图称为用顶点表示活动的网络(Activity On Ve…

小程序介绍和注册安装

小程序介绍和注册安装微信小程序介绍小程序特点其它平台小程序注册微信小程序开发帐号获取appidappid简介微信开发者工具安装创建一个小程序项目核心步骤微信开发者工具构成微信小程序介绍 简短定义&#xff1a;微信小程序是运行在微信APP中的一个程序。 常见小程序 行程码拼…

UDS诊断系列介绍11-3E服务

本文框架1. 系列介绍1.1 3E服务概述2. 3E服务请求与应答2.1 3E服务请求2.2 3E服务正响应2.3 3E服务否定响应3. Autosar系列文章快速链接1. 系列介绍 UDS&#xff08;Unified Diagnostic Services&#xff09;协议&#xff0c;即统一的诊断服务&#xff0c;是面向整车所有ECU的…

# 【笔记】大话设计模式21-23

【笔记】大话设计模式21-23 文章目录【笔记】大话设计模式21-23单例模式21.1 Example21.2 定义21.3 Show me the code一般单例代码(**懒汉模式**)静态初始化&#xff08;**饿汉模式**&#xff09;21.4 总结22 桥接模式22.1 Example22.2 定义22.3 Show me the code22.4 总结23 命…

Code for VeLO 1: Training Versatile Learned Optimizers by Scaling Up

Code for VeLO 1: Training Versatile Learned Optimizers by Scaling Up 这篇文章将介绍一下怎么用VeLO进行训练。 这篇文章基于https://colab.research.google.com/drive/1-ms12IypE-EdDSNjhFMdRdBbMnH94zpH#scrollToRQBACAPQZyB-&#xff0c;将介绍使用learned optimizer in…

入门力扣自学笔记230 C++ (题目编号:2293)

2293. 极大极小游戏 题目&#xff1a; 给你一个下标从 0 开始的整数数组 nums &#xff0c;其长度是 2 的幂。 对 nums 执行下述算法&#xff1a; 设 n 等于 nums 的长度&#xff0c;如果 n 1 &#xff0c;终止 算法过程。否则&#xff0c;创建 一个新的整数数组 newNums …

【Python百日进阶-数据分析】Day226 - plotly的仪表盘go.Indicator()

文章目录一、语法二、参数三、返回值四、实例4.1 Bullet Charts子弹图4.1.1 基本子弹图4.1.2 添加步骤和阈值4.1.3 自定义子弹4.1.4 多子弹4.2 径向仪表图4.2.1 基本仪表4.2.2 添加步骤、阈值和增量4.2.3 自定义仪表图4.3 组合仪表图4.3.1 组合仪表图4.3.2 单角量规图4.3.3 子弹…

Android 深入系统完全讲解(19)

技术的学习关键点 是什么&#xff1f;思路。 而我这里分享一个学习的经典路线&#xff0c;先厘清总框架&#xff0c;找到思路&#xff0c;然后再逐步击破。 这里关于音视频的就是&#xff1a; 总体分为几部分&#xff1a; 1 绘制 2 编解码格式 3 Android 平台的 FFmpeg 开源移…

Compressed Sensing——从零开始压缩感知

Problem 考虑一个线性方程组求解问题&#xff1a; Axb(1)A x b \tag{1}Axb(1) 其中&#xff0c;A∈RmnA \in\mathbb R^{m\times n}A∈Rmn&#xff0c;x∈Rn1x \in\mathbb R^{n\times 1}x∈Rn1&#xff0c;b∈Rm1b \in\mathbb R^{m\times 1}b∈Rm1且m≪nm \ll nm≪n 这是一个…

【C++11】—— lambda表达式

目录 一、lambda表达式的简介 二、lambda表达式的基本语法 三、lambda表达式的使用方法 四、lambda表达式的底层原理 一、lambda表达式的简介 lambda表达式就类似于仿函数&#xff0c;相比仿函数要更加的简洁&#xff0c;我们看一下下面的代码&#xff1a; //商品类 struct…

【项目实战】使用MybatisPlus乐观锁插件功能

一、背景 当要更新一条记录时&#xff0c;希望这条记录没有被别人更新&#xff0c;可以考虑使用MybatisPlus乐观锁插件功能来实现以上需求。 二、乐观锁介绍 2.1 乐观锁是什么&#xff1f; 乐观锁是一种乐观思想&#xff0c;即认为读多写少&#xff0c;遇到并发的可能性低&…

使用ASM框架创建ClassVisitor时遇到IllegalArgumentException的一种可能解决办法

背景 ASM是java语言中最为广泛使用的插装框架&#xff0c;其优点在于可以动态地在运行时改变java系统的行为&#xff0c;加入我们自己的逻辑。在软件测试领域应用广泛。但是其使用难度很高&#xff0c;一方面使用asm框架需要对java底层知识有较高的了解&#xff0c;另一方面网…

网页共享电脑屏幕与播放(带声音)

这次项目我们是写的一个课堂辅助软件的网页版&#xff0c;其中有一个功能感觉能作为我们项目的一个亮点&#xff0c;就是直播功能&#xff0c;在之前并没有写过这个东西。虽然现在这个功能还不知道怎么写&#xff0c;但是它的流程终归是利用视频流将本地的视频给共享出去&#…

Verilog:【8】基于FPGA实现SD NAND FLASH的SPI协议读写

碎碎念&#xff1a; 终于熬过了期末周&#xff0c;可以开始快乐的开发之旅了。 这一期作为一千粉后的首篇博客&#xff0c;由于之后项目会涉及到相关的部分&#xff0c;因此介绍的是使用FPGA实现SD NAND FLASH的读写操作&#xff0c;以雷龙科技提供的SD NAND FLASH样品为例&…

实证分析权重系数计算大全

在实际研究中&#xff0c;权重计算是一种常见的分析方法&#xff0c;需要结合数据的特征情况进行选择&#xff0c;比如数据之间的波动性是一种信息量&#xff0c;那么可考虑使用CRITIC权重法或信息量权重法&#xff1b;也或者专家打分数据&#xff0c;那么可使用AHP层次法或优序…

直观感受PromQL及其数据类型

由于PromQL内容较多&#xff0c;将内容分为三篇文章讲述&#xff1a; 一、直观感受PromQL及其数据类型 二、PromQL之选择器和运算符 三、PromQL之函数 想必都知道要使用Msql&#xff0c;必须会用SQL&#xff0c;同样要使用Prometheus 就要掌握PromQL&#xff08;Prometheus Que…

【链表】leetcode142.环形链表II(C/C++/Java/Js)

leetcode142.环形链表II1 题目2 思路2.1 判断链表是否有环--快慢指针法2.2 如果有环&#xff0c;如何找到这个环的入口2.3 补充3 代码3.1 C版本3.2 C版本3.3 Java版本3.4 JavaScript版本4 总结1 题目 题源链接 给定一个链表的头节点 head &#xff0c;返回链表开始入环的第一个…

软测复习05:基于质量特征的测试

作者&#xff1a;非妃是公主 专栏&#xff1a;《软件测试》 个性签&#xff1a;顺境不惰&#xff0c;逆境不馁&#xff0c;以心制境&#xff0c;万事可成。——曾国藩 文章目录性能测试压力测试容量测试健壮性测试安全性测试可靠性测试恢复性测试协议一致性测试兼容性测试安装…