首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Unity3D 即時解析 XML:WWW 載入與 XmlDocument.LoadXml

     編輯:程式設計綜合問答

問題現象

使用 WWW 載入 XML 字串後,呼叫 XmlDocument.Load(www.text) 拋出錯誤。

錯誤原因

XmlDocument.Load(string) 期望參數為 **檔案路徑** 或 **URL**,而非 XML 字串內容。需使用 LoadXml(string) 載入字串。

錯誤代碼


IEnumerator GetTime() {
    WWW www = new WWW(timeURL);
    yield return www;
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.Load(www.text); // 錯誤:Load 接受路徑,不是字串
    // ...
}

正確代碼:使用 LoadXml


IEnumerator GetTime() {
    WWW www = new WWW(timeURL);
    yield return www;
    
    if (!string.IsNullOrEmpty(www.error)) {
        Debug.LogError("載入失敗: " + www.error);
        yield break;
    }
    
    try {
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(www.text); // 正確:載入 XML 字串
        
        XmlElement root = xmlDoc.DocumentElement;
        XmlNodeList timeNodes = root.SelectNodes("/ntsc/time");
        
        foreach (XmlElement timeEl in timeNodes) {
            foreach (XmlElement child in timeEl.ChildNodes) {
                switch (child.Name) {
                    case "year": Debug.Log("Year: " + child.InnerText); break;
                    case "month": Debug.Log("Month: " + child.InnerText); break;
                    case "day": Debug.Log("Day: " + child.InnerText); break;
                    case "hour": Debug.Log("Hour: " + child.InnerText); break;
                    case "minite": Debug.Log("Minute: " + child.InnerText); break; // 注意拼寫
                    case "second": Debug.Log("Second: " + child.InnerText); break;
                }
            }
        }
    } catch (XmlException e) {
        Debug.LogError("XML 解析錯誤: " + e.Message);
    } catch (Exception e) {
        Debug.LogError("解析異常: " + e.Message);
    }
}

現代 UnityWebRequest 替代 WWW (Unity 2017.2+)


IEnumerator GetTimeModern() {
    using (UnityWebRequest request = UnityWebRequest.Get(timeURL)) {
        yield return request.SendWebRequest();
        
        if (request.result != UnityWebRequest.Result.Success) {
            Debug.LogError("請求失敗: " + request.error);
            yield break;
        }
        
        string xmlText = request.downloadHandler.text;
        ParseXml(xmlText);
    }
}

void ParseXml(string xmlText) {
    XmlDocument xmlDoc = new XmlDocument();
    xmlDoc.LoadXml(xmlText);
    // ... 同樣解析邏輯
}

效能優化:XmlReader 串流解析 (大 XML 檔案)


void ParseWithXmlReader(string xmlText) {
    using (StringReader sr = new StringReader(xmlText))
    using (XmlReader reader = XmlReader.Create(sr)) {
        while (reader.Read()) {
            if (reader.NodeType == XmlNodeType.Element) {
                switch (reader.Name) {
                    case "year":
                    case "month":
                    case "day":
                    case "hour":
                    case "minite":
                    case "second":
                        reader.Read(); // 移至文字節點
                        Debug.Log(reader.Name + ": " + reader.Value);
                        break;
                }
            }
        }
    }
}

優勢:不載入整個 DOM 到記憶體,適合大檔案、低記憶體裝置。

XML 命名空間處理


// 若 XML 有命名空間:
XmlNamespaceManager nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("ns", "https://example.com/ns");
XmlNodeList nodes = xmlDoc.SelectNodes("/ns:ntsc/ns:time", nsmgr);

總結

  • LoadXml(string) 載入 XML 字串,**Load(string)** 載入檔案/URL
  • Unity 2017.2+ **棄用 WWW**,改用 UnityWebRequest
  • 大 XML 用 XmlReader 串流解析省記憶體
  • 命名空間需用 XmlNamespaceManager 配合 XPath
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved