簡體   English   中英

XmlException:缺少根元素。 我正在使用教程創建 xml 加載和保存系統,但我不知道錯誤在哪里

[英]XmlException: Root element is missing. I am creating a xml load and save system using a tutorial but I can't figure out where the error is

這是錯誤消息:

XmlException: Root element is missing.
System.Xml.XmlTextReaderImpl.Throw (System.Exception e) (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo (System.String res) (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.XmlTextReaderImpl.ParseDocumentContent () (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.XmlTextReaderImpl.Read () (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.XmlTextReader.Read () (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.XmlReader.MoveToContent () (at <3df1727680a4410c8922c5d71cde3a04>:0)
Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderActorContainer.Read4_ActorCollection () (at <c06125c6813e448a84b3586be54913c5>:0)
System.Reflection.RuntimeMethodInfo.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) (at <e40e5a8f982c4b618a930d29f9bd091c>:0)
Rethrow as InvalidOperationException: There is an error in XML document (0, 0).
System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.XmlReader xmlReader, System.String encodingStyle, System.Xml.Serialization.XmlDeserializationEvents events) (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.Serialization.XmlSerializer.Deserialize (System.Xml.XmlReader xmlReader, System.String encodingStyle) (at <3df1727680a4410c8922c5d71cde3a04>:0)
System.Xml.Serialization.XmlSerializer.Deserialize (System.IO.Stream stream) (at <3df1727680a4410c8922c5d71cde3a04>:0)
GenshinImpactMovementSystem.SaveData.LoadActors (System.String path) (at Assets/GenshinImpactMovementSystem/Scripts/Characters/Player/Data/XML/SaveData.cs:54)
GenshinImpactMovementSystem.SaveData.Load (System.String path) (at Assets/GenshinImpactMovementSystem/Scripts/Characters/Player/Data/XML/SaveData.cs:19)
GenshinImpactMovementSystem.GameController+<>c.<OnEnable>b__9_1 () (at Assets/GenshinImpactMovementSystem/Scripts/Controllers/GameController.cs:76)
UnityEngine.Events.InvokableCall.Invoke () (at <4a31731933e0419ca5a995305014ad37>:0)
UnityEngine.Events.UnityEvent.Invoke () (at <4a31731933e0419ca5a995305014ad37>:0)
UnityEngine.UI.Button.Press () (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:70)
UnityEngine.UI.Button.OnPointerClick (UnityEngine.EventSystems.PointerEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/UI/Core/Button.cs:114)
UnityEngine.EventSystems.ExecuteEvents.Execute (UnityEngine.EventSystems.IPointerClickHandler handler, UnityEngine.EventSystems.BaseEventData eventData) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:57)
UnityEngine.EventSystems.ExecuteEvents.Execute[T] (UnityEngine.GameObject target, UnityEngine.EventSystems.BaseEventData eventData, UnityEngine.EventSystems.ExecuteEvents+EventFunction`1[T1] functor) (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/ExecuteEvents.cs:272)
UnityEngine.EventSystems.EventSystem:Update() (at Library/PackageCache/com.unity.ugui@1.0.0/Runtime/EventSystem/EventSystem.cs:501)

我不確定錯誤是什么,但我認為這是因為 xml 文件是空白的,但在教程中應該已經編寫了代碼。 我使用 4 個腳本來創建保存和加載系統。

演員劇本:

using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using UnityEngine;

namespace GenshinImpactMovementSystem
{
public class Actor : MonoBehaviour
{
    public ActorData data =  new ActorData();

    public string name = "actor";

    public void StoreData()
    {
        data.name = name;
        Vector3 pos = transform.position;
        data.posX = pos.x;
        data.posY = pos.y;
        data.posZ = pos.z;
    }

    public void LoadData()
    {
        name = data.name;
        transform.position = new Vector3(data.posX, data.posY, data.posZ);
    }

    void OnEnable() 
    {
        SaveData.OnLoaded += delegate { LoadData(); };
        SaveData.OnBeforeSave += delegate { StoreData(); };
        SaveData.OnBeforeSave += delegate { SaveData.AddActorData(data); };
    }

    void OnDisable() 
    {
        SaveData.OnLoaded -= delegate { LoadData(); };
        SaveData.OnBeforeSave -= delegate { StoreData(); };
        SaveData.OnBeforeSave -= delegate { SaveData.AddActorData(data); };
    }
}

public class ActorData
{
    [XmlAttribute("Name")]
    public string name;
    
    [XmlElement("PosX")]
    public float posX;

    [XmlElement("PosY")]
    public float posY;

    [XmlElement("PosZ")]
    public float posZ;
}
}

演員容器腳本:

using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using UnityEngine;

namespace GenshinImpactMovementSystem
{
    [XmlRoot("ActorCollection")]
    public class ActorContainer 
    {
        [XmlArray("Actors")]
        [XmlArrayItem("Actor")]
        public List<ActorData> actors = new List<ActorData>();
    }
}

保存數據腳本:

using System.Collections;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.IO;
using UnityEngine;

namespace GenshinImpactMovementSystem
{
    public class SaveData
    {
        public static ActorContainer actorContainer = new ActorContainer();

        public delegate void SerializeAction();
        public static event SerializeAction OnLoaded;
        public static event SerializeAction OnBeforeSave;

        public static void Load(string path)
        {
            actorContainer = LoadActors(path);

            foreach (ActorData data in actorContainer.actors)
            {
                GameController.CreateActor(data, GameController.playerPath, new Vector3(data.posX, data.posY, data.posZ), Quaternion.identity);
            }

            OnLoaded();
        }

        public static void Save(string path, ActorContainer actors)
        {
            OnBeforeSave();

            SaveActors(path, actors);

            ClearActors();
        }

        public static void AddActorData(ActorData data)
        {
            actorContainer.actors.Add(data);
        }

        public static void ClearActors()
        {
            actorContainer.actors.Clear();
        }

        private static ActorContainer LoadActors(string path)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ActorContainer));

            FileStream stream = new FileStream(path, FileMode.Create);

            ActorContainer actors = serializer.Deserialize(stream) as ActorContainer;

            stream.Close();

            return actors;
        }

        private static void SaveActors(string path, ActorContainer actors)
        {
            XmlSerializer serializer = new XmlSerializer(typeof(ActorContainer));

            FileStream stream = new FileStream(path, FileMode.Open);

            serializer.Serialize(stream, actors);

            stream.Close();
        }
    }
}

游戲 controller:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Cinemachine;
using TMPro;

namespace GenshinImpactMovementSystem
{
    public class GameController : MonoBehaviour
    {
        public Button saveButton;
        public Button loadButton;

        public CinemachineVirtualCamera camera;

        public const string playerPath = "Prefabs/Player";

        private static string dataPath = string.Empty;

        void Awake() 
        {
            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                dataPath = System.IO.Path.Combine(Application.persistentDataPath, "GenshinImpactMovementSystem/Resources/actors.xml");
            }
            else
            {
                dataPath = System.IO.Path.Combine(Application.dataPath, "GenshinImpactMovementSystem/Resources/actors.xml");
            }
        }

        void Start()
        {
            CreateActor(playerPath, new Vector3(0, 0, 0), Quaternion.identity);
        }

        public static Actor CreateActor(string path, Vector3 position, Quaternion rotation)
        {
            GameObject prefab = Resources.Load<GameObject>(path);

            GameObject go = GameObject.Instantiate(prefab, position, rotation) as GameObject;

            Player playerScript = go.GetComponent<Player>();
            
            Transform cameraLookAt = playerScript.cameraPointLookAt;

            CinemachineVirtualCamera cam = FindObjectOfType<CinemachineVirtualCamera>();

            cam.Follow = cameraLookAt;
            cam.LookAt = cameraLookAt;

            playerScript.CameraRecenteringUtility.VirtualCamera = cam;

            Actor actor = go.GetComponent<Actor>() ?? go.AddComponent<Actor>();

            return actor;
        }

        public static Actor CreateActor(ActorData data, string path, Vector3 position, Quaternion rotation)
        {
            GameObject prefab = Resources.Load<GameObject>(path);

            GameObject go = GameObject.Instantiate(prefab, position, rotation);

            Actor actor = go.GetComponent<Actor>() ?? go.AddComponent<Actor>();

            actor.data = data;

            return actor;
        }

        void OnEnable()
        {
            saveButton.onClick.AddListener(delegate {SaveData.Save(dataPath, SaveData.actorContainer);});
            loadButton.onClick.AddListener(delegate {SaveData.Load(dataPath);});
        }

        void OnDisable()
        {
            saveButton.onClick.RemoveListener(delegate {SaveData.Save(dataPath, SaveData.actorContainer);});
            loadButton.onClick.RemoveListener(delegate {SaveData.Load(dataPath);});
        }
    }
}

XML 良構規則只需要一個根元素。

此示例文檔有效:

<doc>
  <entry>...</entry>
  <entry>...</entry>
</doc>

此示例文檔無效,因為有多個頂級元素:

<entry>...</entry>
<entry>...</entry>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM