前言
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()。