Unity XML3——XML序列化

news2024/11/16 23:52:11

一、XML 序列化

​ 序列化:把对象转化为可传输的字节序列过程称为序列化,就是把想要存储的内容转换为字节序列用于存储或传递

​ 反序列化:把字节序列还原为对象的过程称为反序列化,就是把存储或收到的字节序列信息解析读取出来使用

(一)XML 序列化

1.准备数据结构

public class Lesson1Test
{
    public    int          testPublic    = 10;
    private   int          testPrivate   = 11;
    protected int          testProtected = 12;
    internal  int          testInternal  = 13;
    public    string       testPUblicStr = "123";
    public    int          testPro { get; set; }
    public    Lesson1Test2 testClass = new Lesson1Test2();
    public    int[]        arrayInt  = new int[3] { 5, 6, 7 };
    
    public    List<int> listInt = new List<int>() { 1, 2, 3, 4 };
    
    public    List<Lesson1Test2> listItem = new List<Lesson1Test2>() { new Lesson1Test2(), new Lesson1Test2() };

    // 不支持字典
    // public Dictionary<int, string> testDic = new Dictionary<int, string>() { { 1, "123" } };
}

public class Lesson1Test2
{
    public int test1 = 1;
    public float test2 = 1.1f;
    public bool test3 = true;
}

Lesson1Test lt = new Lesson1Test();

2.进行序列化

XmlSerializer:用于序列化对象为 xml 的关键类

StreamWriter:用于存储文件

using:用于方便流对象释放和销毁

using System.Xml.Serialization;

// 第一步:确定存储路径
string path = Application.persistentDataPath + "/Lesson1Test.xml";

// 第二步:结合 using知识点 和 StreamWriter这个流对象 来写入文件
// 括号内的代码:写入一个文件流 如果有该文件 直接打开并修改 如果没有该文件 直接新建一个文件
// using 的新用法 括号当中包裹的声明的对象 会在 大括号语句块结束后 自动释放掉 
// 当语句块结束 会自动帮助我们调用 对象的 Dispose这个方法 让其进行销毁
// using一般都是配合 内存占用比较大 或者 有读写操作时  进行使用的 
using (StreamWriter stream = new StreamWriter(path)) {
    // 第三步:进行xml文件序列化
    XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));
    
    // 这句代码的含义 就是通过序列化对象 对我们类对象进行翻译 将其翻译成我们的xml文件 写入到对应的文件中
    // 第一个参数:文件流对象
    // 第二个参数:想要备翻译 的对象
    // 注意:翻译机器的类型 一定要和传入的对象是一致的 不然会报错
    s.Serialize(stream, lt);
}

3.运行测试

运行后可以看到如下的文件内容(在 path 文件夹中查看)

可以发现,只能保存 public 类型的数据

<?xml version="1.0" encoding="utf-8"?>
<Lesson1Test xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <testPublic>10</testPublic>
  <testPUblicStr>123</testPUblicStr>
  <testClass>
    <test1>1</test1>
    <test2>1.1</test2>
    <test3>true</test3>
  </testClass>
  <arrayInt>
    <int>5</int>
    <int>6</int>
    <int>7</int>
  </arrayInt>
  <listInt>
    <int>1</int>
    <int>2</int>
    <int>3</int>
    <int>4</int>
  </listInt>
  <listItem>
    <Lesson1Test2>
      <test1>1</test1>
      <test2>1.1</test2>
      <test3>true</test3>
    </Lesson1Test2>
    <Lesson1Test2>
      <test1>1</test1>
      <test2>1.1</test2>
      <test3>true</test3>
    </Lesson1Test2>
  </listItem>
  <testPro>0</testPro>
</Lesson1Test>

4.自定义节点名或设置属性

public class Lesson1Test
{
    [XmlElement("testPublic123123")]  // 将该变量对应的结点名字改为 "testPublic123123"
    public    int          testPublic    = 10;
    private   int          testPrivate   = 11;
    protected int          testProtected = 12;
    internal  int          testInternal  = 13;
    public    string       testPUblicStr = "123";
    public    int          testPro { get; set; }
    public    Lesson1Test2 testClass = new Lesson1Test2();
    public    int[]        arrayInt  = new int[3] { 5, 6, 7 };

    [XmlArray("IntList")]    // 改变数组对应的结点名字
    [XmlArrayItem("Int32")]  // 改变数组成员对应的结点名字
    public List<int> listInt = new List<int>() { 1, 2, 3, 4 };

    public List<Lesson1Test2> listItem = new List<Lesson1Test2>() { new Lesson1Test2(), new Lesson1Test2() };

    // 不支持字典
    // public Dictionary<int, string> testDic = new Dictionary<int, string>() { { 1, "123" } };
}

public class Lesson1Test2
{
    [XmlAttribute("Test1")]    // 将该变量存储为XML属性,并改名为 "Test1"
    public int test1 = 1;
    
    [XmlAttribute]             // 将该变量存储为XML属性
    public float test2 = 1.1f;
    
    [XmlAttribute]          
    public bool test3 = true;
}
<?xml version="1.0" encoding="utf-8"?>
<Lesson1Test xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <testPublic>10</testPublic>
  <testPUblicStr>123</testPUblicStr>
  <testClass Test1="1" test2="1.1" test3="true" />
  <arrayInt>
    <int>5</int>
    <int>6</int>
    <int>7</int>
  </arrayInt>
  <IntList>
    <Int32>1</Int32>
    <Int32>2</Int32>
    <Int32>3</Int32>
    <Int32>4</Int32>
  </IntList>
  <listItem>
    <Lesson1Test2 Test1="1" test2="1.1" test3="true" />
    <Lesson1Test2 Test1="1" test2="1.1" test3="true" />
  </listItem>
  <testPro>0</testPro>
</Lesson1Test>

​5. 总结:

  • 序列化流程
    1. 有一个想要保存的类对象
    2. 使用 XmlSerializer 序列化该对象
    3. 通过 StreamWriter 配合 using 将数据存储 写入文件
  • 注意:
    1. 只能序列化公共成员
    2. 不支持字典序列化
    3. 可以通过特性修改节点信息或者设置属性信息
    4. Stream 相关要配合 using 使用

二、XML 反序列化

(一)判断文件是否存在

using System.IO;

string path = Application.persistentDataPath + "/Lesson1Test.xml";
if(File.Exists(path)) { ... }

(二)反序列化

​ 关键知识:

  1. using 和 StreamReader
  2. XmlSerializer 的 Deserialize 反序列化方法
using System.Xml.Serialization;

// 读取文件
using (StreamReader reader = new StreamReader(path))
{
    // 产生了一个 序列化反序列化的翻译机器
    XmlSerializer s = new XmlSerializer(typeof(Lesson1Test));
    Lesson1Test lt = s.Deserialize(reader) as Lesson1Test;
}

​ 运行后调试,可以发现 List 类型的内容被重复添加,原因是变量 lt 初始化后, List 中有默认值,而反序列化时,Deserialize 方法会往 List 中用 Add 方法添加值,而不是覆盖原有的值。

​ 总结:

  1. 判断文件是否存在 File.Exists()

  2. 文件流获取 StreamReader reader = new StreamReader(path)

  3. 根据文件流 XmlSerializer 通过 Deserialize 反序列化出对象

​ 注意:List 对象如果有默认值,反序列化时不会清空,会往后面添加

三、IXmlSerializable 接口

​ C# 的 XmlSerializer 提供了可拓展内容,可以让一些不能被序列化和反序列化的特殊类能被处理
​ 让特殊类继承 IXmlSerializable 接口,实现其中的方法即可

(一)回顾序列化与反序列化

using System.IO;
using System.Xml;
using System.Xml.Serialization;

public class TestLesson3 : IXmlSerializable
{
    public int test1;
    public string test2;
}

TestLesson3 t = new TestLesson3();
t.test2 = "123";
string path = Application.persistentDataPath + "/TestLesson3.xml";
// 序列化
using (StreamWriter writer = new StreamWriter(path))
{
    // 序列化"翻译机器"
    XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
    // 在序列化时  如果对象中的引用成员 为空 那么xml里面是看不到该字段的
    s.Serialize(writer, t);
}
// 反序列化
using (StreamReader reader = new StreamReader(path))
{
    // 序列化"翻译机器"
    XmlSerializer s = new XmlSerializer(typeof(TestLesson3));
    TestLesson3 t2 = s.Deserialize(reader) as TestLesson3;
}
<?xml version="1.0" encoding="utf-8"?>
<TestLesson3 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1>0</test1>
  <test2>123</test2>
</TestLesson3>

(二)继承 IXmlSerializable 接口

1.继承接口并实现接口函数

public class TestLesson3 : IXmlSerializable
{
    public int test1;
    public string test2;

    // 返回结构,返回 null 即可,不用过多了解
    public XmlSchema GetSchema()
    {
        return null;
    }

    // 反序列化时 会自动调用的方法
    public void ReadXml(XmlReader reader) { }

    // 序列化时 会自动调用的方法
    public void WriteXml(XmlWriter writer) { }
}

2.WriteXml

public void WriteXml(XmlWriter writer)
{
    // 在里面可以自定义序列化 的规则

    // 如果要自定义 序列化的规则 一定会用到 XmlWriter中的一些方法 来进行序列化
    // 1.写属性
    writer.WriteAttributeString("test1", this.test1.ToString());
    writer.WriteAttributeString("test2", this.test2);

    // 2.写节点
    writer.WriteElementString("test1", this.test1.ToString());
    writer.WriteElementString("test2", this.test2);

    // 3.写包裹节点
    XmlSerializer s = new XmlSerializer(typeof(int));
    writer.WriteStartElement("test1");  // 写 <test1>
    s.Serialize(writer, test1);         // 用序列化翻译机器写 test1 的内容
    writer.WriteEndElement();           // 写 </test1>

    XmlSerializer s2 = new XmlSerializer(typeof(string));
    writer.WriteStartElement("test2");  // 写 <test2>
    s.Serialize(writer, test2);         // 用序列化翻译机器写 test2 的内容
    writer.WriteEndElement();           // 写 </test2>
}

3.ReadXml

public void ReadXml(XmlReader reader)
{
    // 在里面可以自定义反序列化 的规则
    // 1.读属性
    this.test1 = int.Parse(reader["test1"]);
    this.test2 = reader["test2"];

    // 2.读节点
    // 方式一
    reader.Read();                         // 这时是读到的test1节点          <test1>
    reader.Read();                         // 这时是读到的test1节点包裹的内容  0
    this.test1 = int.Parse(reader.Value);  // 得到当前内容的值=
    reader.Read();                         // 这时读到的是尾部包裹节点        </test1>
    reader.Read();                         // 这时是读到的test2节点          <test2>
    reader.Read();                         // 这时是读到的test2节点包裹的内容  123
    this.test2 = reader.Value;

    // 方式二
    while (reader.Read()) 
    {
        if (reader.NodeType == XmlNodeType.Element) 
        {
            switch (reader.Name) 
            {
                case "test1":
                    reader.Read();
                    this.test1 = int.Parse(reader.Value);
                    break;
                case "test2":
                    reader.Read();
                    this.test2 = reader.Value;
                    break;
            }
        }
    }

    // 3.读包裹元素节点
    XmlSerializer s = new XmlSerializer(typeof(int));
    XmlSerializer s2 = new XmlSerializer(typeof(string));

    reader.Read();  // 跳过根节点
    
    reader.ReadStartElement("test1");     // 读 <test1>
    test1 = (int)s.Deserialize(reader);   // 用反序列化翻译机器读 test1 的内容
    reader.ReadEndElement();              // 读 </test1>

    reader.ReadStartElement("test2");            // 读 <test2>
    test2 = s2.Deserialize(reader).ToString();   // 用反序列化翻译机器读 test2 的内容
    reader.ReadEndElement();                     // 读 </test2>
}

四、Dictionary 支持序列化与反序列化

  1. 我们没办法修改 C# 自带的类

  2. 那我们可以重写一个类继承 Dictionary,然后让这个类继承序列化拓展接口 IXmlSerializable

  3. 实现里面的序列化和反序列化方法即可

public class SerizlizedDictionary<TKey, TValue> : Dictionary<TKey, TValue>, IXmlSerializable
{
    public XmlSchema GetSchema() {
        return null;
    }

    // 自定义字典的 反序列化 规则
    public void ReadXml(XmlReader reader) {
        XmlSerializer keySer   = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        // 要跳过根节点
        reader.Read();
        // 判断 当前不是元素节点 结束 就进行 反序列化
        while (reader.NodeType != XmlNodeType.EndElement) {
            // 反序列化键
            TKey key = (TKey)keySer.Deserialize(reader);
            // 反序列化值
            TValue value = (TValue)valueSer.Deserialize(reader);
            // 存储到字典中
            this.Add(key, value);
        }
    }

    // 自定义 字典的 序列化 规则
    public void WriteXml(XmlWriter writer) {
        XmlSerializer keySer   = new XmlSerializer(typeof(TKey));
        XmlSerializer valueSer = new XmlSerializer(typeof(TValue));

        foreach (KeyValuePair<TKey, TValue> kv in this) {
            // 键值对 的序列化
            keySer.Serialize(writer, kv.Key);
            valueSer.Serialize(writer, kv.Value);
        }
    }
}

(一)序列化测试

public class TestLesson4
{
    public int test1;

    public SerizlizerDictionary<int, string> dic;
}

public class Lesson4 : MonoBehaviour
{
    // Start is called before the first frame update
    void Start() {
        TestLesson4 tl4 = new TestLesson4();
        tl4.dic = new SerizlizerDictionary<int, string>();
        tl4.dic.Add(1, "123");
        tl4.dic.Add(2, "234");
        tl4.dic.Add(3, "345");
        
        string path = Application.persistentDataPath + "/TestLesson4.xml";
        using (StreamWriter writer = new StreamWriter(path)) {
            XmlSerializer s = new XmlSerializer(typeof(TestLesson4));
            s.Serialize(writer, tl4);
        }
    }
}
<?xml version="1.0" encoding="utf-8"?>
<TestLesson4 xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <test1>0</test1>
  <dic>
    <int>1</int>
    <string>123</string>
    <int>2</int>
    <string>234</string>
    <int>3</int>
    <string>345</string>
  </dic>
</TestLesson4>

(二)反序列化测试

void Start() {
    TestLesson4 tl4 = new TestLesson4();
    using (StreamReader reader = new StreamReader(path)) {
        XmlSerializer s = new XmlSerializer(typeof(TestLesson4)); 
        tl4 = s.Deserialize(reader) as TestLesson4;
    }
}

五、自定义 XML 数据管理类

using System;
using System.IO;
using System.Xml.Serialization;
using UnityEngine;

public class XmlDataMgr
{
    // 单例模式
    public static XmlDataMgr Instance { get; } = new XmlDataMgr();

    // 防止外部实例化该管理类
    private XmlDataMgr() { }

    /// <summary>
    /// 保存数据到xml文件中
    /// </summary>
    /// <param name="data">数据对象</param>
    /// <param name="fileName">文件名</param>
    public void SaveData(object data, string fileName) {
        // 1.得到存储路径
        string path = Application.persistentDataPath + "/" + fileName + ".xml";
        // 2.存储文件
        using (StreamWriter writer = new StreamWriter(path)) {
            // 3.序列化
            XmlSerializer s = new XmlSerializer(data.GetType());
            s.Serialize(writer, data);
        }
    }

    /// <summary>
    /// 从xml文件中读取内容 
    /// </summary>
    /// <param name="type">对象类型</param>
    /// <param name="fileName">文件名</param>
    /// <returns></returns>
    public object LoadData(Type type, string fileName) {
        // 1.首先要判断文件是否存在
        string path = Application.persistentDataPath + "/" + fileName + ".xml";
        if (!File.Exists(path)) {
            path = Application.streamingAssetsPath + "/" + fileName + ".xml";
            if (!File.Exists(path)) {
                // 如果根本不存在文件 两个路径都找过了
                // 那么直接new 一个对象 返回给外部 无非 里面都是默认值
                return Activator.CreateInstance(type);
            }
        }
        // 2.存在就读取
        using (StreamReader reader = new StreamReader(path)) {
            // 3.反序列化 取出数据
            XmlSerializer s = new XmlSerializer(type);
            return s.Deserialize(reader);
        }
    }
}
  if (!File.Exists(path)) {
            path = Application.streamingAssetsPath + "/" + fileName + ".xml";
            if (!File.Exists(path)) {
                // 如果根本不存在文件 两个路径都找过了
                // 那么直接new 一个对象 返回给外部 无非 里面都是默认值
                return Activator.CreateInstance(type);
            }
        }
        // 2.存在就读取
        using (StreamReader reader = new StreamReader(path)) {
            // 3.反序列化 取出数据
            XmlSerializer s = new XmlSerializer(type);
            return s.Deserialize(reader);
        }
    }
}

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

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

相关文章

再见 MyBatis-Plus !

一、Mybatis-Flex是什么&#xff1f; Mybatis-Flex 是一个优雅的 Mybatis 增强框架&#xff0c;它非常轻量、同时拥有极高的性能与灵活性。我们可以轻松的使用 Mybaits-Flex 链接任何数据库&#xff0c;其内置的 QueryWrapper^亮点 帮助我们极大的减少了 SQL 编写的工作的同时…

odoo16-domain

odoo16-domain 参考:https://blog.csdn.net/u013250491/article/details/86699928 domain的使用注意以下几点: 是在py文件中使用还是在xml中使用,py文件是在后端使用可以利用orm, 而xml是在前端渲染,使用的是js,没有办法使用orm如果在xml中使用,domain的格式建议为[[]], 二维…

LeetCode32.Longest-Valid-Parentheses<最长有效括号>

题目&#xff1a; 思路&#xff1a; 遍历括号.遇到右括号然后前一个是左括号 那就res2,然后重定位 i 的值 并且长度减少2; 但是问题在于无法判断最长的括号.只能得到string内的全部括号长度. 错误代码: 写过一题类似的,那题是找括号数.记得是使用的栈,但是死活写不出来. 看完…

【Visual Studio Code】加载saved_model.pb时报错缺失‘cudart64_110.dll‘等

如果报错Could not load dynamic library cudart64_110.dll; dlerror: cudart64_110.dll not found&#xff0c; 将对应的cudart64_110.dll复制到C:\Windows\System32下即可 如果VScode仍继续报错&#xff0c;重新启动软件即解决问题。 同理&#xff0c;若仍有相同报错 Cou…

ios私钥证书的创建方法

ios私钥证书是苹果公司为ios开发者打包app&#xff0c;推出的一种数字证书&#xff0c;只有同一个苹果开发者账号生成的ios私钥证书打的包&#xff0c;才能上架同一个开发者账号的app store。因此不要指望别人给你共享私钥证书和描述文件&#xff0c;因为别人的证书和描述文件打…

Ubuntu Server版 之 apache系列 安装、重启、开启,版本查看

安装之前首先要检测是否安装过 apt list --installed | grep tool tool&#xff1a;要检测的名称&#xff0c;如mysql、apache 、ngnix 等 安装 apache sudo apt install apache2 安装apache 默认是开启的 可以通过浏览器 检测一下 service apache stop # apache 停止服务…

道本科技||全面建立国有企业合规管理体系

为全面深化国有企业法治建设&#xff0c;不断加强合规管理&#xff0c;防控合规风险&#xff0c;保障企业稳健发展&#xff0c;近日&#xff0c;市国资委印发《常州市市属国有企业合规管理办法&#xff08;试行&#xff09;》&#xff08;以下简称《办法》&#xff09;&#xf…

包装设计软件 CubeDesigner[CubeMaster] 10.0 Crack

CubeDesigner 是一款包装设计软件&#xff0c;旨在支持包装专业人员创建最佳的包装设计和托盘图案。借助 CubeDesigner&#xff0c;您可以轻松确定优化的船箱尺寸、布置、托盘配置和卡车装载。CubeDesigner提供不同级别的服务&#xff0c;以满足不同用户的需求。CubeDesigner f…

Go语法入门 + 项目实战

&#x1f442; Take me Hand Acoustic - Ccile Corbel - 单曲 - 网易云音乐 第3个小项目有问题&#xff0c;不能在Windows下跑&#xff0c;懒得去搜Linux上怎么跑了&#xff0c;已经落下进度了.... 目录 &#x1f633;前言 &#x1f349;Go两小时 &#x1f511;小项目实战 …

深度学习:BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解

深度学习&#xff1a;BatchNorm、LayerNorm、InstanceNorm、GroupNorm和SwitchableNorm的理解 深度学习中的NormBatchNormLayerNormInstanceNormGroupNormSwitchableNorm 附录 深度学习中的Norm 在深度学习中会经常遇到BatchNorm、LayerNorm、InstanceNorm和GroupNorm&#xf…

queue

文章目录 定义分类链式队列静态队列循环队列静态队列为什么必须是循环队列&#xff1f;循环队列需要几个参数&#xff1f;循环队列入队伪代码循环队列出队伪代码判断循环队列是否为空判断循环队列是否已满 循环队列的代码实现队列的应用 定义 一种可以实现“先进先出”的存储结…

postcss-pxtorem适配插件动态配置rootValue(根据文件路径名称,动态改变vue.config里配置的值)

项目背景&#xff1a;一个项目里有两个分辨率的设计稿(1920和2400)&#xff0c;不能拆开来打包 参考&#xff1a; 是参考vant插件&#xff1a;移动端Vant组件库rem适配下大小异常的解决方案&#xff1a;https://github.com/youzan/vant/issues/1181 说明&#xff1a; 因为vue.c…

Java代码审计7之XSS

文章目录 1、漏洞代码2、修复XSS2.1、单个文件修复2.2、通用过滤 3、一些补充 之前的文章&#xff0c; php代码审计14之XSS 1、漏洞代码 xssServlet.java package com.example.demo; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; im…

windows安装Elasticsearch8.9.0

官网解压安装好路径&#xff08;非中文&#xff0c;无空格&#xff09; 可参考 言之有李LAX csdn http://t.csdn.cn/S2oju本人使用jdk17 修改配置elasticsearch.yml xpack.security.enabled: false xpack.security.http.ssl:enabled: false直接点击bin\elasticsearch.bat…

二叉树的链式结构 - 遍历 - C语言递归实现

前序、中序以及后序遍历 二叉树遍历 (Traversal) 是按照某种特定的规则&#xff0c;依次对二叉 树中的节点进行相应的操作&#xff0c;并且每个节点只操作一次 。 按照规则&#xff0c;二叉树的遍历有&#xff1a; 前序/中序/后序 的递归结构遍历 &#xff1a; 1. 前序遍历(P…

2023天津Java培训学校分享!Java培训班

近年来&#xff0c;各类培训机构如雨后春笋般涌现&#xff0c;其中&#xff0c;Java培训机构可谓是风头正盛&#xff0c;许多想踏入这行的小伙伴选择这个方式来学习Java技能&#xff0c;今天我们一起来讨论一下&#xff1a;学Java有门槛吗&#xff0c;Java培训的好处&#xff0…

问题解决:VS Code环境调试多文件C++程序

在VS code环境下默认可以调试单文件的C程序&#xff0c;如果是多文件的程序&#xff0c;则会出现编译不通过的问题&#xff0c;无法进行调试 解决方法 在VS Code的工程目录下&#xff0c;有一个tasks.json文件 修改tasks.json文件 其中&#xff0c;"args"子项里面…

android app控制ros机器人三(android登录界面)

接下来是二次开发的具体环节了&#xff0c;由于存在用户需求&#xff0c;用到ros-mobile不多&#xff0c;更偏向于android开发。 用ppt画了简单的展示界面&#xff0c;与用后交流界面的功能布局。先开发一代简易版本的app&#xff0c;后续可以丰富完善。ctrlcv上线。 登录界面…

图数据库Neo4j学习三——cypher语法总结

1MATCH 1.1作用 MATCH是Cypher查询语言中用于从图数据库中检索数据的关键字。它的作用是在图中查找满足指定条件的节点和边&#xff0c;并返回这些节点和边的属性信息。 在MATCH语句中&#xff0c;通过节点标签和边类型来限定查找范围&#xff0c;然后通过WHERE语句来筛选符合…

vue+leaflet笔记之地图量测

vueleaflet笔记之地图量测 文章目录 vueleaflet笔记之地图量测开发环境代码简介插件简介与安装使用简介图形量测动态量测 详细源码(Vue3) 本文介绍了Web端使用Leaflet开发库进行距离量测的一种方法 (底图来源:天地图)&#xff0c;结合leaflet-measure-path插件能够快速的实现地…