一文看懂Unity3D(C#)读取解析xml配置文件及key=value配置文件

相关知识点:

Unity3D如何配置全局xml配置文件并进行读取解析

C#读取xml文件时如何忽略掉注释部分



总结网上的读取方式大致分为两种:

1, 将xml文件放在Assets/StreamingAssets 文件下, 然后通过 WWW() 方式读取到xml文件的字符串内容, 然后使用mono.xml插件进行解析

2, 将xml文件放在Assets/Resources 文件下, 然后通过 Resources.Load()方法读取到xml文件的stream, 然后用C#的IO及XML的相关api进行解析

关于以上两个方法注意点:

文件名一定要与上述相同,不然Unity读取不到

使用Resources.Load()方法读取时, 只写文件名, 不要加.xml后缀


如果通过Resources.Load()方法获取到的一直是null并且能够确定文件路径及名称都没问题,那就是遇到另一个坑了:

在Unity中在xml文件上右键,然后 选择Reimport,重新导入一下xml文件


因为非专业人员,所以没有深入研究mono.xml插件, 使用第二种方法,用C#原生api进行解析:

转自 : https://blog.csdn.net/u013108312/article/details/62045236



    
        c++
        570
    
    
        c#
        110
    
using Mono.Xml;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Security;
using System.Xml;
using UnityEngine;

public class ReadXML : MonoBehaviour {

    // Use this for initialization
    void Start () {

        //TextAsset ta = Resources.Load("test", typeof(TextAsset)) as TextAsset;
        //ReadXMlTest(new MemoryStream(ta.bytes));

        StartCoroutine(StartTxt());

    }

    // Update is called once per frame
    void Update () {

    }

    IEnumerator StartTxt()
    {
        WWW www = new WWW("file://" + Application.streamingAssetsPath + "/test.xml");
        yield return www;

        //ReadXMlTest(new MemoryStream(www.bytes));
        ReadXMLMono(www.text);
        www.Dispose();
    }

    void ReadXMlTest(Stream stream)
    {
        XmlDocument xmldoc = new XmlDocument();
        xmldoc.Load(stream);
        XmlNode info = xmldoc.SelectSingleNode("info");
        foreach (XmlNode node in info.ChildNodes)
        {
            string id = node.Attributes["id"].Value;
            string lang = node.Attributes["lang"].Value;

            string name = node.SelectSingleNode("name").InnerText;
            string price = node.SelectSingleNode("price").InnerText;

            Debug.Log("node.Name:" + node.Name + " id:"+ id + " lang:" + lang + " name:" + name + " price:" + price);
        }
    }

    void ReadXMLMono(string text)
    {
        SecurityParser sp = new SecurityParser();
        sp.LoadXml(text);
        SecurityElement se = sp.ToXml();

        foreach (SecurityElement sel in se.Children)
        {
            string id = (string)sel.Attributes["id"];
            string lang = (string)sel.Attributes["lang"];

            string name = "", price = "";
            foreach (SecurityElement se2 in sel.Children)
            {
                if (se2.Tag == "name")
                {
                    name = se2.Text;
                }
                else if (se2.Tag == "price")
                {
                    price = se2.Text;
                }
            }
            Debug.Log(" id:" + id + " lang:" + lang + " name:" + name + " price:" + price);
        }
    }
}


解决在其他脚本的Start()方法执行之前进行全局配置文件的解析:

随便建一个GlobalInit脚本, 添加一个 方法,方法名随意, 在方法上面添加如下注解:

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void OnGameLoaded()
    {
        //读取配置文件
        TextAsset app = Resources.Load("App");
        ReadXMl(new MemoryStream(app.bytes));
    }



忽略掉xml中的注释:

C#解析xml时候会自动将注释内容也算在内, 忽略注释的方法:

网上找到的方法大致如下:

XmlDocument doc = new XmlDocument();  
XmlReaderSettings settings = new XmlReaderSettings();  
settings.IgnoreComments = true;  
//xmlFilePath:xml文件路径  
XmlReader reader = XmlReader.Create(xmlFilePath, settings);  
doc.Load(reader);   

但是这里稍有不同,因为不是通过文件路径进行读取了, 而是传入stream流进行读取,所以做如下改动:

static void ReadXMl(Stream stream)
    {
        XmlDocument xmldoc = new XmlDocument();
        XmlReaderSettings settings = new XmlReaderSettings();
        //忽略xml文件的注释
        settings.IgnoreComments = true;
        XmlReader xr = XmlReader.Create(stream, settings); //第一个参数不一定是路径, 可以是文件的stream
        xmldoc.Load(xr);

        XmlNode configuration = xmldoc.SelectSingleNode("configuration");
        XmlNode info = configuration.SelectSingleNode("appSettings");
        foreach (XmlNode node in info.ChildNodes)
        {
            string key = node.Attributes["key"].Value;
            string value = node.Attributes["value"].Value;
            App.Add(key, value);
        }
    }


最终完整代码如下:

xml:



  
    
    
    
    
  

脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//读取配置文件相关
using System.IO;
using System.Xml;

public class Chushihua : MonoBehaviour {

    //全局配置文件
    public static Dictionary App = new Dictionary();

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
		
	}

    /**
     * 在所有文件加载之前执行
     */
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    static void OnGameLoaded()
    {
        //读取配置文件
        TextAsset app = Resources.Load("App");
        ReadXMl(new MemoryStream(app.bytes));
    }

    static void ReadXMl(Stream stream)
    {
        XmlDocument xmldoc = new XmlDocument();

        XmlReaderSettings settings = new XmlReaderSettings();
        //忽略xml文件的注释
        settings.IgnoreComments = true;
        XmlReader xr = XmlReader.Create(stream, settings);
        xmldoc.Load(xr);

        XmlNode configuration = xmldoc.SelectSingleNode("configuration");
        XmlNode info = configuration.SelectSingleNode("appSettings");
        foreach (XmlNode node in info.ChildNodes)
        {
            string key = node.Attributes["key"].Value;
            string value = node.Attributes["value"].Value;
            App.Add(key, value);
        }

    }

}

其他脚本中使用:

    private string SERVER_IP; //服务器ip
    private string SERVER_PORT; //服务器端口号

    void Start()
    {
        SERVER_IP = Chushihua.App["SERVER_IP"];
        SERVER_PORT = Chushihua.App["SERVER_PORT"];
    }


网上找到的另一篇教程, 根据字符串内容分隔截取的方法, 没有尝试,应该也可行

针对如下key,value格式的配置文件

username=tom

password=123456

https://blog.csdn.net/leonardo_davinci/article/details/78344224

你可能感兴趣的:(C#,Unity3D)