Xml数据持久化储存

Xml是什么?

Xml全称为:Extensible Markup Lauguage;

文件的后缀名为: .xml

Xml文本编辑器

 一般的文档编辑器都可以编辑xml文件,常用的打开xml文件的方式有:

1、系统自带的记事本。(本人常用)

2、专用的xml文本编辑器-XMLSprear。

3、通用的文本编辑器-Subline Text。    

Xml的一些基本语法

1、<!--你要写的内容-->

这个写法相当于注释。//

2、<?xml version=“ ” encoding=“ ”?>

这个格式是固定格式,相当于交代了xml的版本和编码格式。例如UTF-8。非常important!

3、<>你要写的内容</>

xml是一个树形结构,一个根节点,后面是子节点。而编写的格式就是类似这样。

<Data>
    <name>张三</name>
    <age>999</age>
    <item>
        <id>1</id>
        <num>1</num>
    </item>
    <item2 name="xx" id='0'/>
</Data>

4、一些特殊的符号

&lt -小于<

&gt -大于>

&amp -&和号

&apos -‘单引号

&quot -“双引号

Xml的属性语法

<!--属性就是元素标签后面的空格,添加的内容-->
<!--属性必须用引号包裹-->
<Friend name="Erden Lord" age='999'>我的宝藏</Friend>
<!--如果属性记录不想使用元素标记那就这么写如下-->
<Friend name="ghost" age='999'/>

两者写法按自己喜好来。

检查语法错误 

1、元素标签必须配对

2、属性必须有引号

3、注意命名

或者在 https://www.runoob.com/xml/xml-validator.html 

上面进行验证。

C#读取储存Xml 

1、文件存放位置

1、只读不写文件夹下:Resource或StreamingAssets文件夹下。

2、动态储存的xml文件:Aplication.persistentDataPath 路径下。

2、读取Xml文件信息

1、XmlDocument(数据加载到内存中,方便读取)

2、XmlTextReader(以流形式加载,内存占用少,但是只能单向读取)

3、Linq

XmlDocument xml=new XmlDocument();
//通过此方法读取有两个方法,1:直接根据xml字符串内容加载
TextAsset asset=Resource.Load<TextAsset>("TestXml");
xml.LoadXml(asset.text);
//2:通过Xml文件的路径进行加载
xml.Load(Application.streamingAssetsPath + "/TestXml.xml");

 3、读取元素和属性信息

XmlNode/XmlNodeList     节点信息类/节点列表信息类

//获取Xml中的根节点
XmlNode root=xml.SelectSingleNode("Data");
//再获取其下的子节点
XmlNode nodename=root.SelectSingleNode("name");
//如果想直接获取节点包裹的元素信息,直接 .InnerText
print(nodename.InnerText); 

//若要是得到属性,则有Attributes
XmlNode nodeID=root.SelectSingleNode("item2");
//也有如下两个写法
print(nodeID.Attributes["id"].Value);
print(nodeID.Attributes.GetNamedItem("id").Value);

//这里是获取一个节点下具有同名的节点的方法
XmlNodeList friendlist=root.SelectNodes("Friend"); 
//遍历的话有for和迭代器两种方法不做展示了。
  

  储存Xml文件

关键类:XmlDocument(用于创建节点储存文件),XmlDeclaration(用于添加版本信息),XmlElement(节点类)     

//决定储存在哪个文件夹下
//1、Rsources 可读不可写,打包后找不到
//2、Application.streamingAssetsPath 可读,PC端可写,找的到
//3、Application.dataPath 打包后找不到
//4、Application.persistentDataPath 可读可写找的到
string path =Application.persistentDataPath+"/test.xml"
//创建文本对象
XmlDocument xml=new XmlDocument();
//添加固定版本信息
XmlDeclaration xmlDec=xml.CreateXmlDeclaration("1.0","UTF-8","");
//创建完成后添加进入文本对象中
xml.AppendChild(XmlDec);
//添加根节点
XmlElement root =xml.CreateElement("root");
xml.AppendChild(root);
//为根节点添加子节点
XmlElement name=xml.CreateElement("name");
name.InnerText="xxxx";
root.AppendChild(name);
//保存
xml.Save(test);

修改Xml文件

//先判断是否存在文件
if(File.Exists(path))
{
    //加载后,直接添加或移除即可
    XmlDocument newxml =new XmlDocument();
    newxml.Load(path);
    //下面两种写法
    XmlNode node=newxml.SeclectSingleNode("Root").SelectSingleNode("name");
    node =newxml.SelectSingleNode("Root/name");
    //得到自己的父节点
    XmlNode rootp=newxml.SeclectSingleNode("Root");
    //移除子节点
    rootp.RemoveChild(node);
}

C#中Xml的序列化/反序列化

序列化:将对象转化成可传输的字节序列过程。

反序列化:将收到或储存的的字节序列信息进行解析出来。

Xml的序列化

步骤:1、准备一个数据结构类,2、进行序列化

XmlSerializar  用于序列化对象为Xml的关键类。

StreamWriter 用于储存文件

using 用于方便流对象的创建和销毁

1、

public class Test
{
    public int testpublic =1;
    private int testprivate =2;
    protected int testprotected =3;
    Internal int  testInternal =4;
    
    public string testPublicStr ="abc";
    
    public int TEST { get,set};
    
    public Test2 testclass=new Test2();

}

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

2、

Test ts =new Test();
//创建一个路径
string path =Application.persistentDataPath+"/Test.xml";

//写入一个文件流,如果有该文件,直接打开并修改,如果没有,就会创建一个文件
//using 括号中包裹的对象会在语句块结束后自动释放掉
//原因在于streamwriter继承自TextWriter
//TextWriter有一个IDisposable这个接口中有个方法Dispose会帮助在结束后销毁
//using一般用于 内存占用大 或 有读写操作时 进行使用。
using(streamWriter streamWrit =new streamWriter(path))
{
    //进行xml文件序列化
    XmlSerializer xs= new XmlSerializer (typeof(Test));
    xs.Serialize(streamWrit,ts);
}

 PS:1、这种方式只能存储公共的成员。

        2、无法对字典类型的成员进行序列化,但List类型是可以的。

        3、序列化主要用于动态存储。

自定义节点名 或 设置属性:

1、[XmlAttribute()]

2、[XmlElement()]

3、[XmlArray()]

4、[XmlArrayItem()]。

Xml的反序列化

在反序列化前,首先需要对需要反序列化的路径进行确认文件存在与否。

会用到:1、XmlSerializer的Deserialize的方法。

 2、StreamReader和using。

string path =Application.persistentDataPath+"/Test.xml";
if(File.Exists(path))
{
    using(StreamReader reader =new StreamReader(path))
    {
        XmlSerializer xs= new XmlSerializer(typeof(Test));
        Test i=xs.Deserialize(reader) as Test;
    }
}

反序列化的时候会对原本的List中的默认值进行添加,所以对此我们最好不要在原本的类中的List成员进行初始值赋值。

IXmlSerializable接口

这个用于解决Xml文件无法对公共字典成员序列化的问题。

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

public class Test3 :IXmlSerializable
{
    public int ts1;
    public string ts2;
    //返回结构
    public XmlSchema GetSchema()
    {
        return null;
    }

    //反序列化时会调用这个
    public void ReadXml(XmlReader reader)
    {
        //可以自定义反序列化规则
        
        //1、读属性
        this.ts1=int.Parse(reader["ts1"]);
        this.ts2=reader["ts2"];
        //2、读节点
        while(reader.Read())
        {
            if(reader.NodeType==XmlNodeType.Element)
            {
                switch(reader.Name)
                {    
                    case "ts1":
                        reader.Read();
                        this.ts1=int.Parse(reader.Value);    
                        break;
                    case "ts2":
                        reader.Read();
                        this.ts2=reader.Value;
                        break;
                }
            }
        }
        //3、读包裹节点元素
        XmlSerializer s=new XmlSerializer(typeof(int));
        //跳过根节点
        reader.Read();
        reader.ReadStartElement("ts1");
        ts1=(int)s.Deserialize(reader);
        reader.ReadEndElement();
    }

    //序列化时会调用这个
    public void WriteXml(XmlWriter writer)   
    {
        //可以自定义序列化规则
        //1、写属性
        writer.WriteAttributeString("ts1",this.ts1.ToString());
        writer.WriteAttrbuteString("ts2",this.ts2);
        //2、写节点
        writer.WriteElementString("ts1",this.ts1.ToString());
        writer.WriteElementString("ts2",this.ts2);
        //3、写包裹节点
        XmlSerializer s=new XmlSerializer(typeof(int));
        writer.WriteStartElement("ts1");
        s.Serialize(writer,ts1);
        writer.WriteEndElement();
    }
}
Test3 t=new Test3();
string path =Application.persistentDataPath+"/Test3.xml";
//序列化
using(StreamWriter writer =new StreamWriter(path))
{
    XmlSerializer s =new XmlSerializer(typeof(Test3));
    s.Serialize(writer,t);
}
//反序列化
using(StreamReader reader =new StreamReader(path))
{
    XmlSerializer s =new XmlSerializer(typeof(Test3));
    Test3 t3=s.Deserialize(reader,t) as Test3;
}

 

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值