前言

xml是可扩展标记语言,由一系列的元素、属性、值节点等构成的一个树形结构,除了可读性差一点,别的用于存储一些结构化的数据还是比较方便的。这个功能在Unity3d端的实现是比较方便快捷的:

void GetXML1() {
    string filePath = Application.streamingAssetsPath + "/xml1.xml";
    if (File.Exists(filePath))
    {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.Load(filePath); 
        XmlNodeList nodes = xmlDoc.SelectSingleNode("rootitem").ChildNodes;
        foreach (XmlNode node in nodes)
        {
            Debug.Log(node.Name + ":" + node.InnerText);
        }
    }
     else
        Debug.LogError("xml文件1不存在:" + filePath);
   }

如上的代码,将xml文件放到StreamingAssets文件夹下,使用XmlDocument.Load函数直接加载,让后通过XmlNodeList可以快速的解析。
xml文件的内容如下:

<?xml version="1.0" encoding="utf-8"?>
  <!--以下为正式内容-->
<rootitem>
  <labone>老铁666</labone>
  <!--这是xml1的文件-->
</rootitem>

在Unity3d端或者pc端都能正确的解析输出:
在这里插入图片描述

WebGL问题

同样如上的代码放到WebGL平台就无法正常使用,虽然在Unity出包WebGL的时候没有任何的异常,但是运行起来就无法正常加载:
在这里插入图片描述

可以看到xml文件找不到这个log是我自己的判断if (File.Exists(filePath))为false导致的。

直接打开文件

而且我直接访问地址是可以在浏览器中打开xml文件的localhost/TestWebGLBuilds/StreamingAssets/xml1.xml:
在这里插入图片描述

直接加载

那么如果放弃文件是否存在判断直接XmlDocument.Load函数来加载呢:

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filePath); 
XmlNodeList nodes = xmlDoc.SelectSingleNode("rootitem").ChildNodes;
foreach (XmlNode node in nodes)
{
     Debug.Log(node.Name + ":" + node.InnerText);
}

这样也无法加载,报错如下:
在这里插入图片描述

修改路径

尝试修改filePath的值如下:

string filePath = "/StreamingAssets/xml1.xml";

直接加载XmlDocument.Load:
在这里插入图片描述

string filePath = "StreamingAssets/xml1.xml";

文件路径判定File.Exists:
在这里插入图片描述

上面的修改也是无效的。

正确加载解析

经过一段时间的尝试和测试,终于找到了一个在Windows端和WebGL端都能正常加载解析的方法:

   void GetXML2()
    {
        StartCoroutine(GetRequest(Application.streamingAssetsPath + "/xml2.xml"));
    }


    IEnumerator GetRequest(string uri)
    {
        using (UnityWebRequest webRequest = UnityWebRequest.Get(uri))
        {
            yield return webRequest.SendWebRequest();

            if (webRequest.error == null)
            {
                Debug.Log("xml文件2:" + webRequest.downloadHandler.text); 
                XmlDocument xmlDoc = new XmlDocument();
                xmlDoc.LoadXml(webRequest.downloadHandler.text);

                XmlNodeList nodes = xmlDoc.SelectSingleNode("rootitem").ChildNodes;
                foreach (XmlNode node in nodes)
                {
                    Debug.Log(node.Name + ":" + node.InnerText);  
                }
            }
            else
            {

                Debug.LogError("xml文件2异常:" + webRequest.error);
            }
          }
    }

新建一个xml2.xml的文件:

<?xml version="1.0" encoding="utf-8"?>
  <!--以下为正式内容-->
<rootitem>
  <labtwo>老铁没毛病666</labtwo>
  <!--这是xml2的文件-->
</rootitem>

可以看到WebGL端也能正常加载解析:
在这里插入图片描述

这个实现方式是通过UnityWebRequest来加载xml文件内容,XmlDocument.LoadXml()来加载解析内容。

总结

之前的实现方式具体问题可能是路径问题或者Load函数平台不支持。这两种可能性都有,不过目前都没有验证。因为使用错误路径(如:“/StreamingAssets/xml1.xml”)时,使用XmlDocument.Load来加载会提示路径错误;而使用Application.streamingAssetsPath时,也不是提示路径错误,而是报错:
Invoking error handler due to Uncaught abort(43) at Error
at jsStackTrace (TestWebGLBuilds.wasm.framework.unityweb:8:15602)
因为我也没在Unity文档中找到具体的支持信息 。
所以具体是路径问题?还是库支持问题?目前还没法确定。
不过要兼容WebGL平台的可用方式就是加载使用UnityWebRequest.Get,解析使用XmlDocument.LoadXml()。

Logo

分享前沿Unity技术干货和开发经验,精彩的Unity活动和社区相关信息

更多推荐