Java SE 学习笔记(十九)—— XML、设计模式

news2024/12/24 3:56:47

目录

  • 1 XML
    • 1.1 XML 概述
    • 1.2 XML 语法规则
    • 1.3 XML 文档约束(了解)
      • 1.3.1 DTD 约束
      • 1.3.2 schema 约束
  • 2 XML 解析
    • 2.1 XML 解析概述
    • 2.2 Dom4J 解析 XML 文件
    • 2.3 XML 解析案例
  • 3 XML 检索
  • 4 设计模式
    • 4.1 工厂模式
    • 4.2 装饰模式

1 XML


在有些业务场景下,存储数据或者传输数据给别人的时候需要满足一定的规范进行组织

1.1 XML 概述


XML 的全称为(EXtensible Markup Language),是一种 可扩展标记语言,是一种数据表示格式,可以用于自定义数据格式,可以描述非常复杂的数据结构,常用于传输和存储数据。

例如:

<?xml version="1.0" encoding="UTF-8"?>
<data>
	<sender> 张三 </sender>
	<receiver> 李四 </receiver>
	<src>
		<addr> 北京 </addr>
		<date>2022-11-11 11:11:11</date>
	</src>
	<current> 武汉 </current>
	<dest> 广州 </dest>
</data>

XML 的几个特点和使用场景

  • 一是纯文本,默认使用 UTF-8 编码;二是可嵌套;
  • 如果把 XML 内容存为文件,那么它就是一个 XML 文件。
  • XML 内容经常被 当成消息进行网络传输,或者 作为配置文件用于存储系统的信息

1.2 XML 语法规则


  1. XML 的创建

就是创建一个 XML 类型的文件,要求文件的后缀名必须使用 xml,如:helloworld.xml

  1. XML 文件的文档声明

XML 文件的文档声明必须在第一行

<?xml version="1.0" encoding="UTF-8" ?>

version : XML 默认的版本号码、该属性是必须存在的
encoding :本 XML 文件的编码

  1. XML 的标签 ( 元素 ) 规则
  • 标签由一对尖括号和合法标识符组成:<name></name>,必须存在一个根标签,有且只能有一个
  • 标签必须成对出现,有开始,有结束 : <name></name>
  • 特殊的标签可以不成对,但是必须有结束标记,如 :<br/>
  • 标签中可以定义属性,属性和标签名空格隔开 ,属性值必须用引号引起来 <student id = “1”></name>
  • 标签需要正确的嵌套
  • XML 文件中可以定义注释信息: <!-- 注释内容 -->
  • XML 文件中可以存在以下特殊字符
    • &lt;< 小于
    • &gt;> 大于
    • &amp;& 和号
    • &apos;' 单引号
    • &quot;" 引号
  • XML 文件可以存在 CDATA 区 (IDEA中输入CD再回车)

示例代码

<?xml version="1.0" encoding="UTF-8" ?>
<student>
    <msg>
        age &gt; 18 &amp;&amp; age &lt;24
    <![CDATA[
        age>18 && age<24
    ]]>
    </msg>
</student>

1.3 XML 文档约束(了解)


问题:由于 XML 文件可以自定义标签,导致 XML 文件可以随意定义,程序在解析的时候可能出现问题。

文档约束是用来限定 XML 文件中的标签以及属性应该怎么写,以此强制约束程序员必须按照文档约束的规定来编写 XML 文件中

文档约束可以分为:DTD和 schema 两种

1.3.1 DTD 约束


需求:利用 DTD 文档约束,约束一个 XML 文件的编写。

分析:

  • 编写 DTD 约束文档,后缀必须是 .dtd
  • 在需要编写的 XML 文件中导入该 DTD 约束文档
  • 按照约束的规定编写 XML 文件的内容

示例代码

在这里插入图片描述

XML 的文档约束 -DTD 的作用和问题?

  • 可以约束 XML 文件的编写。
  • 不能约束具体的数据类型。

1.3.2 schema 约束


schema 可以约束具体的数据类型,约束能力上更强大,但由于其本身也是一个 XML 文件,也受到其他约束文件的要求,所以编写地更严谨

需求:利用 schema 文档约束,约束一个 XML 文件的编写。

分析:

  • 编写 schema 约束文档,后缀必须是 .xsd
  • 在需要编写的 XML 文件中导入该 schema 约束文档
  • 按照约束内容编写 XML 文件的标签。

示例代码

在这里插入图片描述

2 XML 解析

2.1 XML 解析概述


XML 的数据的作用是什么,最终需要怎么处理?

  • 存储数据、做配置信息、进行数据传输。
  • 最终需要被程序进行读取,解析里面的信息。

主要有两种解析方式: SAX 解析、DOM 解析

Dom 常见的解析工具

在这里插入图片描述

DOM 解析解析文档对象模型

在这里插入图片描述

Document 对象:整个 xml 文档
Node 对象

  • Element 对象:标签
  • Attribute 对象:属性
  • Text 对象:文本内容

2.2 Dom4J 解析 XML 文件


需求:使用 Dom4J 把一个 XML 文件的数据进行解析

分析:

  • 下载 Dom4j 框架,官网下载。
  • 在项目中创建一个文件夹: lib
  • 将 dom4j-2.1.1.jar 文件复制到 lib 文件夹
  • 在 jar 文件上点右键,选择 Add as Library -> 点击 OK
  • 在类中导包使用

Dom4j 解析 XML- 得到 Document 对象

SAXReader类

在这里插入图片描述

Document 类

在这里插入图片描述

Dom4j 解析 XML 的元素、属性、文本

在这里插入图片描述

示例代码

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<contactList>
    <contact id="1" vip="true">哈哈哈
        <name>   潘金莲  </name>
        <gender></gender>
        <email>panpan@it.cn</email>
    </contact>
    <contact id="2" vip="false">
        <name>武松</name>
        <gender></gender>
        <email>wusong@it.cn</email>
    </contact>
    <contact id="3" vip="false">
        <name>武大狼</name>
        <gender></gender>
        <email>wuda@it.cn</email>
    </contact>
    <user>
    </user>
</contactList>

解析XML文件

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;
import java.io.InputStream;

public class Dom4jDemo {
    @Test
    public void parseXML() throws Exception{
        // 1. 创建一个Dom4j解析器对象,代表了整个Dom4j框架
        SAXReader saxReader = new SAXReader();
        // 2. 把XML文件加载到内存中称为一个Document对象
//        Document document = saxReader.read("xml\\src\\Contacts.xml");
//        Document document = saxReader.read(new File("xml\\src\\Contacts.xml"));
//        Document document = saxReader.read(new FileInputStream("xml\\src\\Contacts.xml"));

        // getResourceAsStream 中的/是直接去src下寻找文件
        InputStream is = Dom4jDemo.class.getResourceAsStream("/Contacts.xml");
        Document document = saxReader.read(is);

        // 3. 获取根元素对象
        Element rootElement = document.getRootElement();
        System.out.println(rootElement.getName()); // contactList

        // 4. 获取子元素
        // 4.1 获取根元素下所有的子元素(一级)
//        List<Element> elements = rootElement.elements();
//        for (Element element : elements) {
//            System.out.println(element.getName());
//        }
        // 4.2 获取某个子元素(若同名,默认提取第一个子元素对象)
        Element contact = rootElement.element("contact");
        System.out.println(contact.getName()); // contact
        // 4.3 获取当前元素的文本
        System.out.println(contact.getText());
        // 去掉前后空格
        System.out.println(contact.getTextTrim()); // 哈哈哈
        // 4.4 获取子元素文本
        System.out.println(contact.elementText("name"));
        // 去掉前后空格
        System.out.println(contact.elementTextTrim("name")); // 潘金莲
        // 4.5 根据元素获取属性值
        Attribute id = contact.attribute("id");
        // 打印属性名和属性值
        System.out.println(id.getName()+":"+id.getValue());
        // 4.6 直接获取属性值
        System.out.println(contact.attributeValue("id")); // 1
        System.out.println(contact.attributeValue("vip")); // true
    }
}

2.3 XML 解析案例


需求 : 利用 Dom4J 的知识,将 Contact.xml 文件中的联系人数据封装成 List 集合,其中每个元素是实体类 Contact 。打印输出 List 中的每个元素。

案例用到的 XML 文件见上文

创建 Contact 类

public class Contact {
    private String name;
    private int id;
    private boolean vip;
    private char gender;
    private String email;

    public Contact() {
    }

    public Contact(String name, int id, boolean vip, char gender, String email) {
        this.name = name;
        this.id = id;
        this.vip = vip;
        this.gender = gender;
        this.email = email;
    }

    public String getName() {
        return name;
    }

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

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public boolean isVip() {
        return vip;
    }

    public void setVip(boolean vip) {
        this.vip = vip;
    }

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    @Override
    public String toString() {
        return "Contact{" +
                "name='" + name + '\'' +
                ", id=" + id +
                ", vip=" + vip +
                ", gender=" + gender +
                ", email='" + email + '\'' +
                '}';
    }
}

解析XML

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.lang.invoke.StringConcatException;
import java.util.ArrayList;
import java.util.List;

public class TestDemo {
    @Test
    public void parseToList() throws Exception {
        // 1. 创建saxReader对象
        SAXReader saxReader = new SAXReader();
        // 2. 加载XML文件成为Document对象
        Document document = saxReader.read(TestDemo.class.getResourceAsStream("/Contacts.xml"));
        // 3. 先获取根元素
        Element rootElement = document.getRootElement();
        // 4. 获取所有的contact子元素
        List<Element> contactEles = rootElement.elements("contact");
        // 5. 准备一个ArrayList集合封装联系人信息
        ArrayList<Contact> contactsList = new ArrayList<>();
        // 6. 遍历每一个contact子元素
        for (Element contactEle : contactEles) {
            // 7. 每一个contact子元素都是一个联系人对象
            Contact contact = new Contact();
            // 8. 提取信息并给对象赋值
            contact.setId(Integer.valueOf(contactEle.attributeValue("id")));
            contact.setVip(Boolean.valueOf(contactEle.attributeValue("vip")));
            contact.setName(contactEle.elementTextTrim("name"));
            contact.setGender(contactEle.elementTextTrim("gender").charAt(0));
            contact.setEmail(contactEle.elementTextTrim("email"));
            // 9.把联系人对象放入List集合
            contactsList.add(contact);
        }
        // 10. 遍历集合
        for (Contact contact : contactsList) {
            System.out.println(contact);
        }
    }
}

输出结果

在这里插入图片描述

总结

  • Dom4J 解析 XML 文件的核心思想
    • 得到文档对象 Document ,从中获取元素对象和内容。
  • Dom4J 的解析后的数据形式。
    • 通常数据会封装成 Java 的对象,如单个对象,或者集合对象形
      式。

3 XML 检索


如果需要从 XML 文件中检索需要的某个信息(如 name )怎么解决?

  • Dom4j 需要进行文件的全部解析,然后再寻找数据。
  • Xpath 技术更加适合做信息检索。

XPath 在解析 XML 文档方面提供了一独树一帜的路径思想,更加优雅,高效。XPath 使用路径表达式来定位 XML 文档中的元素节点或属性节点。

使用 Xpath 检索出 XML 文件

需求:使用 Dom4J 把一个 XML 文件的数据进行解析

分析:

  • 导入 jar 包 (dom4j 和 jaxen-1.1.2.jar) , Xpath 技术依赖 Dom4j 技术
  • 通过 dom4j 的 SAXReader 获取 Document 对象
  • 利用 XPath 提供的 API, 结合 XPath 的语法完成选取 XML 文档元素节点进行解析操作。

Document 中与 Xpath 相关的 API

在这里插入图片描述

Xpath 的四大检索方案

  1. 绝对路径:采用绝对路径获取从根节点开始逐层的查找 /contactList/contact/name 节点列表并打印信息

在这里插入图片描述

  1. 相对路径:先得到根节点 contactList,再采用相对路径获取下一级 contact 节点的 name 子节点并打印信息

在这里插入图片描述

  1. 全文检索:直接全文搜索所有的 name 元素并打印

在这里插入图片描述

  1. 属性查找:在全文中搜索属性,或者带属性的元素

在这里插入图片描述

示例代码

XML文件

<?xml version="1.0" encoding="UTF-8"?>
<contactList>
    <contact id="1" vip="true">
        <name>   潘金莲  </name>
        <gender></gender>
        <email>panpan@itcast.cn</email>
    </contact>
    <contact id="2" vip="false">
        <name>武松</name>
        <gender></gender>
        <email>wusong@itcast.cn</email>
    </contact>
    <contact id="3" vip="false">
        <name>武大狼</name>
        <gender></gender>
        <email>wuda@itcast.cn</email>
    </contact>
    <user>
        <contact>
            <info>

                <name id="666">西门庆</name>
            </info>
         </contact>
    </user>
</contactList>

检索XML

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
import org.junit.Test;

import java.util.List;

public class XPathDemo {

    // 1. 绝对路径
    @Test
    public void parse01() throws Exception {
        // 创建解析器对象
        SAXReader saxReader = new SAXReader();
        // 将XML文件加载成Document对象
        Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));
        // 检索全部名称:name值
        List<Node> nodes = document.selectNodes("/contactList/contact/name");
        for (Node node : nodes) {
            Element nameEle = (Element) node;
            System.out.println(nameEle.getTextTrim());
        }

    }
    // 2. 相对路径
    @Test
    public void parse02() throws Exception {
        // 创建解析器对象
        SAXReader saxReader = new SAXReader();
        // 将XML文件加载成Document对象
        Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));
        Element rootElement = document.getRootElement();
        // 检索全部名称:name值
        List<Node> nodes = rootElement.selectNodes("./contact/name");
        for (Node node : nodes) {
            Element nameEle = (Element) node;
            System.out.println(nameEle.getTextTrim());
        }
    }
    // 3. 全文搜素
    @Test
    public void parse03() throws Exception {
        // 创建解析器对象
        SAXReader saxReader = new SAXReader();
        // 将XML文件加载成Document对象
        Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));
        // 检索数据
//        List<Node> nodes = document.selectNodes("//name");// 会找"西门庆"
//        List<Node> nodes = document.selectNodes("//contact/name");// 不会找"西门庆"
        List<Node> nodes = document.selectNodes("//contact//name");// 会找"西门庆"
        for (Node node : nodes) {
            Element nameEle = (Element) node;
            System.out.println(nameEle.getTextTrim());
        }
    }
    // 4. 属性查找
    @Test
    public void parse04() throws Exception {
        // 创建解析器对象
        SAXReader saxReader = new SAXReader();
        // 将XML文件加载成Document对象
        Document document = saxReader.read(XPathDemo.class.getResourceAsStream("/Contacts2.xml"));
        // 检索数据
        // 在全文中检索属性对象
        List<Node> nodes = document.selectNodes("//@id");
        for (Node node : nodes) {
            Attribute attr = (Attribute) node;
            System.out.println(attr.getName()+":"+attr.getValue());
        }
        // 在全文中检索包含该属性的元素对象(若有多个只返回第一个)
        // 查询name元素(包含id属性的)
//        Node node = document.selectSingleNode("//name[@id]");
        // 在全文中检索属性对象且属性值为该值的元素对象
        Node node = document.selectSingleNode("//name[@id=666]");
        Element ele = (Element) node;
        System.out.println(ele.getTextTrim());
    }
}

Element和继承Node

4 设计模式

4.1 工厂模式


之前我们创建类对象时,都是使用 new 对象的形式创建,在很多业务场景下也提供了不直接 new 的方式 。

工厂模式( Factory Pattern )是 Java 中最常用的设计模式之一, 这种类型的设计模式属于创建型模式,它提供了一种获取对象的方式。

工厂设计模式的作用:

  • 工厂的方法可以封装对象的创建细节,比如:为该对象进行加工和数据注入。
  • 可以实现类与类之间的解耦操作(核心思想)

4.2 装饰模式


装饰设计模式:创建一个新类,包装原始类,从而在新类中提升原来类的功能。

装饰设计模式的作用:

  • 装饰模式指的是在不改变原类的基础上 ,动态地扩展一个类的功能

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (123)-- 算法导论10.4 4题

四、用go语言&#xff0c;对于一个含 n个结点的任意有根树&#xff0c;写出一个 O(n)时间的过程&#xff0c;输出其所有关键字该树以左孩子右兄弟表示法存储。 文心一言&#xff1a; 在计算机科学中&#xff0c;左孩子右兄弟表示法是一种用于表示树状结构的方法&#xff0c;其…

springboot--基本特性--自定义 Banner

SpringApplication的使用 前言效果1.1 自定义banner1.2 自定义SpringApplication配置文件优先级高于程序化调整的优先级启动自定义banner关闭自定义banner 1.3 FluentBuilder API 前言 修改启动时候的修改banner 效果 1.1 自定义banner banner制定官网链接 在配置文件中设置…

sentinel规则持久化-规则同步nacos-最标准配置

官方参考文档&#xff1a; 动态规则扩展 alibaba/Sentinel Wiki GitHub 需要修改的代码如下&#xff1a; 为了便于后续版本集成nacos&#xff0c;简单讲一下集成思路 1.更改pom 修改sentinel-datasource-nacos的范围 将 <dependency><groupId>com.alibaba.c…

Qt之DLL的使用(关联DLL生成篇)

文章目录 一、示例二、使用步骤1.所需文件2.添加库3.选择库4.完成添加5.导入类使用 相关文章 一、示例 下图为使用DLL的示例图 二、使用步骤 1.所需文件 将所需要使用的相关库&#xff08;导出项目的库&#xff0c;包括Debug和Release两个编译模式的库&#xff0c;缺少某个…

【算法优选】前缀和专题——叁

文章目录 &#x1f60e;前言&#x1f334;[和为K的子数组](https://leetcode.cn/problems/subarray-sum-equals-k/description/)&#x1f6a9;题目描述&#x1f6a9;思路解析&#x1f6a9;代码实现 &#x1f384;[和可被 K 整除的子数组](https://leetcode.cn/problems/subarra…

【观察】Dell APEX云平台:引领多云时代上云新范式

毫无疑问&#xff0c;过去十多年是云计算发展的黄金十年&#xff0c;云计算理念不断被市场所接受&#xff0c;但随着企业上云深入和认知度的不断增加&#xff0c;摆在很多企业面前的选择题也发生了新变化&#xff0c;即从过去企业上云或不上云的纠结&#xff0c;转变成今天如何…

在pycharm中,远程操作服务器上的jupyter notebook

一、使用场景 现在我们有两台电脑&#xff0c;一台是拥有高算力的服务器&#xff0c;另一台是普通的轻薄笔记本电脑。如何在服务器上运行jupyter notebook&#xff0c;同时映射到笔记本电脑上的pycharm客户端中进行操作呢&#xff1f; 二、软件 pycharm专业版&#xff0c;jupy…

从一线到联合,克唑替尼在ALK阳性NSCLC治疗新旅程【医游记】

&#xff08;图片来源于网络&#xff09; 一、克唑替尼简介 克唑替尼(Crizotinib),商品名赛可瑞,是一款口服服用的小分子酪氨酸激酶抑制剂。克唑替尼最早于2011年被美国FDA批准用于ALK阳性晚期NSCLC的治疗。其主要靶点为间变淋巴瘤激酶(ALK)和ROS1(ROS proto-oncogene 1)融合…

Beyond Compare4 30天试用到期的2024最新解决办法

对于有文档对比需求的小伙伴们来说&#xff0c;Beyond Compare这款软件一定不陌生&#xff0c;这款软件是一款功能非常强大的文档对比软件。同时这款软件也是一款付费软件&#xff0c;需要用户付费才能够享有Beyond Compare的永久使用权&#xff0c;不过在付费之前&#xff0c;…

【OpenCV实现图像梯度,Canny边缘检测】

文章目录 概要图像梯度Canny边缘检测小结 概要 OpenCV中&#xff0c;可以使用各种函数实现图像梯度和Canny边缘检测&#xff0c;这些操作对于图像处理和分析非常重要。 图像梯度通常用于寻找图像中的边缘和轮廓。在OpenCV中&#xff0c;可以使用cv2.Sobel()函数计算图像的梯度…

部署私有仓库(笔记docker应用)

二&#xff1a;部署私有仓库 docker pull daocloud.io/library/registry:latest docker run --restartalways -d -p 5000:5000 daocloud.io/library/registry systemctl stop firewalld systemctl restart docker 宿主机ip端口 curl -I 127.0.0.1:5000 将镜像存放在仓…

[C++进阶篇]STL以及string的使用

目录 1. 什么是STL 2. STL库的六大组件 3. 标准库中的string类 3.3 对比size和capacity接口函数 size代表字符串有效长度 capacity代表字符串的实际长度 3.4 reserve&#xff0c;resize函数的使用 3.5 string类的访问和遍历 4. string的修改操作 5. insert和e…

3DMAX快速瓦片屋顶铺设插件使用方法详解

3DMAX快速瓦片屋顶铺设插件教程 3DMAX快速瓦片屋顶铺设插件&#xff0c;一键生成瓦片屋顶、瓦脊的插件&#xff0c;是一款非常实用的古风建筑建模插件。 【适用版本】 3dMax7或更新版本 【使用方法】 提示&#xff1a;建议使用本插件进行工作时&#xff0c;将3dMax单位设置为…

松下A6B伺服 马达不动问题解决

本人在用信捷XDH plc ethercat总线&#xff0c;连松下A6B伺服&#xff0c;轴配置完成轴调试时&#xff0c;出现能使能&#xff0c;但 马达不动的情况。 开始总怀疑时信捷PLC的原因&#xff0c;后面查明是输入口定义引起的。 用USB线连接伺服&#xff0c;打开PANAPARM软件,自…

[读论文] On Joint Learning for Solving Placement and Routing in Chip Design

0. Abstract 由于 GPU 在加速计算方面的优势和对人类专家的依赖较少&#xff0c;机器学习已成为解决布局和布线问题的新兴工具&#xff0c;这是现代芯片设计流程中的两个关键步骤。它仍处于早期阶段&#xff0c;存在一些基本问题&#xff1a;可扩展性、奖励设计和端到端学习范…

数据结构 | 顺序表专题

数据结构 | 顺序表专题 文章目录 数据结构 | 顺序表专题课前准备1. 目标2. 需要的储备知识3. 数据结构相关概念 开始顺序表1、顺序表的概念及结构2、顺序表分类3、动态顺序表的实现初始化顺序表打印顺序表内存容量的检查顺序表的尾插顺序表的尾删顺序表的头插顺序表的头删在顺序…

Beyond Compare比较规则设置 Beyond Compare怎么对比表格

在对文件进行比较时&#xff0c;文件夹内的文件可能存在不同类型、不同后缀名、不同内容等差异&#xff0c;这些差异会影响具体的比较结果&#xff0c;因此需要我们对软件的比较规则进行一些设置。接下来就让我们一起来学习一下Beyond Compare比较规则设置&#xff0c;Beyond C…

C语言-递归和迭代

&#x1f308;write in front&#x1f308; &#x1f9f8;大家好&#xff0c;我是Aileen&#x1f9f8;.希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流. &#x1f194;本文由Aileen_0v0&#x1f9f8; 原创 CSDN首发&#x1f412; 如…

ZYNQ连载07-PIN设备

ZYNQ连载07-PIN设备 1. 简述 RT-Thread PIN设备 这里参看RT-Thread提供的PIN设备管理接口&#xff0c;简单封装了几个接口函数。 2. 实现 #include "include/drv_gpio.h" #define LOG_TAG "drv_gpio" static XGpioPs xgpiops;void rt_pin_mode(rt_…