유니티에서 XML파싱을 위해 WWW 클래스로 .XML 파일을 불러왔습니다. 불러들인 정보를 디시리얼라이즈하는 기능은 없나요?(안드로이드폰을 위해 개발중입니다.)

조회수 3406회
 IEnumerator read()

    {
        Text txt = GameObject.Find("ERRORMESSAGE2").GetComponent<Text>();

        string fileName = "Quests.xml";
        string filePath = "jar:file://" + Application.dataPath + "!/assets/" + fileName;

        var www = new WWW(filePath);
        yield return www;
        if (!string.IsNullOrEmpty(www.error))
        {
            txt.text = "로딩실패";
        }
        else if (string.IsNullOrEmpty(www.error))
        {
            txt.text = "로딩성공";
        }
    }

불러들였습니다만 아래 iostream같이 디시리얼라이즈 하는 기능은 없나요?

 void serialize()

{

Type[ ] questType = { typeof(QUEST) };

        XmlSerializer serializer = new XmlSerializer(typeof(QuestContainer), questType);

        TextReader textReader = new StreamReader(filePath);
        QuestContainer = (QuestContainer)serializer.Deserialize(textReader);
        textReader.Close();
        txt.text = (textReader.ReadLine());
    }

불러들인 정보를 아래 양식에 맞게 디시리얼라이즈하는 기능이 필요합니다..

정보는 불러들여진 후 각 프로쎄스로 나눠져 컨테이너로 들어가게됩니다..

public class QuestContainer
{

    private List<QUEST> confirmed = new List<QUEST>();
    private List<QUEST> complete = new List<QUEST>();
    private List<QUEST> possible = new List<QUEST>();
    private List<QUEST> im_possible = new List<QUEST>();

    public List<QUEST> Confirmed
    {
        get { return confirmed; }
        set { confirmed = value; }
    }

    public List<QUEST> Complete
    {
        get { return complete; }
        set { complete = value; }
    }

    public List<QUEST> Possible
    {
        get { return possible; }
        set { possible = value; }
    }

    public List<QUEST> im_Possible
    {
        get { return im_possible; }
        set { im_possible = value; }
    }
}
public class QUEST
{
    public string Questname { get; set; }
    public string Description { get; set; }
    public string Class { get; set; }
    public int Level { get; set; }
    public int STR { get; set; }
    public int CON { get; set; }
    public int INT { get; set; }
    public int WIS { get; set; }
    public int DEX { get; set; }
    public string Title { get; set; }
    public string Item { get; set; }
    public QUEST_TYPE questType { get; set; }
    public DIFFICULTY difficulty { get; set; }
    public EXPEDIENT eXPEDIENT { get; set; }
    public QUEST_REWARD questReward { get; set; }
    public string target { get; set; }
    public int count { get; set; }
    public bool canClear { get; set; }

    public QUEST()
    {

    }

    public QUEST(string Questname,string Description,string Class,int level,int str,int con, int Int, int wis, int dex,string title,string item,  QUEST_TYPE QuestType, DIFFICULTY Difficulty, QUEST_REWARD quest_reward, EXPEDIENT EXPEDIENT, string Target, int Count, bool canclear)
    {
        this.Description = Description;
        this.Questname = Questname;
        this.questType = QuestType;
        this.difficulty = Difficulty;
        this.eXPEDIENT = EXPEDIENT;
        this.questReward = quest_reward;
        this.Class = Class;
        this.Level = level;
        this.STR = str;
        this.CON = con;
        this.INT = Int;
        this.WIS = wis;
        this.DEX = dex;
        this.Title = title;
        this.Item = item;
        this.target = Target;
        this.count = Count;
        this.canClear = canclear;
    }
<?xml version="1.0" encoding="utf-8"?>
<QuestContainer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <Confirmed>
    <QUEST>
      <Questname>시작</Questname>
      <Description>이제 시작이에요!</Description>
      <Class>ALL</Class>
      <Level>0</Level>
      <STR>0</STR>
      <CON>0</CON>
      <INT>0</INT>
      <WIS>0</WIS>
      <DEX>0</DEX>
      <Title />
      <Item />
      <questType>ROOP</questType>
      <difficulty>EASY</difficulty>
      <eXPEDIENT>MOVE</eXPEDIENT>
      <questReward>GOLD</questReward>
      <target>Bank</target>
      <count>10</count>
      <canClear>false</canClear>
    </QUEST>
  </Confirmed>
  <Complete />
  <Possible />
  <im_Possible />
</QuestContainer>

그런 기능이 없다면 수작업으로 주입하는 방법이라도 알려주시면 좋겠습니다.

추가사항 -

alt text

  • 수정 감사합니다. 정토드 2016.2.16 11:54

4 답변

  • XmlSerialization을 이용하는게 좋겠네요. 안드로이드에서 loadXML()까지는 확인했고 write는 유니티에디터에서만 동작 확인해 봤습니다.

    참고로 List에서 아이템을 지울때는 반복문에서 지우면 안되더군요. tmp만들어서 옮긴담에 지웠으니 코드 확인요.

    using UnityEngine;
    using System.Collections;
    using System.Xml;
    using System.Collections.Generic;
    using System.Xml.Serialization;
    using System.IO;
    
    
    public class NewBehaviourScript : MonoBehaviour {
        QuestContainer container;
        void Start () {
            loadXML ();
    
            List<QUEST> tmp = new List<QUEST> ();
            foreach (QUEST quest in container.Confirmed) {
                container.Complete.Add (quest);
                tmp.Add (quest);
            }
    
            foreach (QUEST quest in tmp) {
                container.Confirmed.Remove (quest);
            }
    
            writeXML ();
    
    
        }
    
        void loadXML(){
            TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
            var serializer = new XmlSerializer(typeof(QuestContainer));
            StringReader stream = new StringReader (textAsset.ToString ());
            container = serializer.Deserialize(stream) as QuestContainer;
            stream.Close();
            Debug.Log ("Confirmed");
            foreach (QUEST quest in container.Confirmed) {
                Debug.Log (quest.Questname);
            }
    
            Debug.Log ("Complete");
            foreach (QUEST quest in container.Complete) {
                Debug.Log (quest.Questname);
            }                                            
        }
    
        void writeXML(){
            var serializer = new XmlSerializer (typeof(QuestContainer));
            var stream = new FileStream(pathForDocumentsFile("tmp.xml"), FileMode.Create);
            serializer.Serialize(stream, container);
            stream.Close();
        }
    
        public string pathForDocumentsFile( string filename ) 
        {
            if (Application.platform == RuntimePlatform.IPhonePlayer)
            {
                string path = Application.dataPath.Substring( 0, Application.dataPath.Length - 5 );
                path = path.Substring( 0, path.LastIndexOf( '/' ) );
                return Path.Combine( Path.Combine( path, "Documents" ), filename );
            }
            else if(Application.platform == RuntimePlatform.Android)
            {
                string path = Application.persistentDataPath; 
                path = path.Substring(0, path.LastIndexOf( '/' ) ); 
                return Path.Combine (path, filename);
            } 
            else 
            {
            string path = Application.dataPath; 
            path = path.Substring(0, path.LastIndexOf( '/' ) );
            return Path.Combine (path, filename);
            }
        }
    }
    

    수정: 더 좋은 방법 발견해서 아래 방법은 별로인것 같네요.

    코드에 IEnumerator가 있는걸 보니...유니티에서 작업중이셨네요. 다음과 같이 하시면 될것 같습니다.

    using UnityEngine;
    using System.Collections;
    using System.Xml;
    using System.Collections.Generic;
    public class XMLParsing : MonoBehaviour{
      QuestContainer qc;
      void Awake(){
        qc = new QuestContainer();
      }
    
      void parseXML(Text txt){
        XmlDocument xmlDoc = new XmlDocument();
        xmlDoc.LoadXml(txt);
            XmlNodeList xnList; 
    
        //Confirmed
        xnList= xml.SelectNodes("/QuestContainer/Confirmed/QUEST");    
        foreach(XmlNode node in xnList)
        {
          Quest quest = new Quest();
          quest.QuestName = xn["QuestName"].InnerText;
          quest.Level = int.Parse(xn["Level"].InnerText);
          qc.confirmed.Add(quest);
        }
    
        //같은 방식으로 Complete, Possible, impossible처리
      }
    }
    
  • 유니티에서 파일을 불러들이시려면 Resources폴더에 파일을 넣어 두어야 합니다. Assets아래에 Resources폴더가 없으시면 만드시고, 그 안에 XML파일을 넣어두세요. 그리고 다음 코드를 참고해서 QuestContainer로 XML을 읽어들이도록 만들면 됩니다. http://www.w3schools.com/xml/cd_catalog.xml 에서 받을 수 있는 xml파일을 Resources폴더에 Catalog.xml로 넣어 두었습니다. 참고로 Resources에서 파일을 읽어올때는 확장자를 안붙여줘도 되요.

    유니티에서 돌려본 코드니까 잘 될겁니다.

    using UnityEngine;
    using System.Collections;
    using System.Xml;
    using System.Collections.Generic;
    
    public class NewBehaviourScript : MonoBehaviour {
        List<CD> confirmed= new List<CD>();
    
        // Use this for initialization
        void Start () {
            parseXML ();
    
    
        }
    
        // Update is called once per frame
        void Update () {
    
        }
    
        void parseXML(){
    
            TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
            XmlDocument xmlDoc = new XmlDocument ();
            xmlDoc.LoadXml ( textAsset.text );
            XmlNodeList xnList; 
    
            //Confirmed
            xnList= xmlDoc.SelectNodes("/CATALOG/CD");    
            foreach(XmlNode node in xnList)
            {
    
                CD cd = new CD();
                cd.title = node["TITLE"].InnerText;
                Debug.Log(cd.title);
                cd.artist = node["ARTIST"].InnerText;
                confirmed.Add(cd);
            }
    
            //같은 방식으로 Complete, Possible, impossible처리
        }
    }
    
    public class CD{
        public string title;
        public string artist;
    }
    
    

    질문을 올려주실때, 모두 코드로 올려주시면 더 자세히 설명이 가능할 것 같은데, XML파일은 이미지 캡쳐로 올려주시고, Quest클래스의 정의도 안올려주시니 어쩔수 없이 다른 파일을 예로 들었네요.

    • 질문에 대한 내용은 댓글로 달아주시면 좋겠습니다. 정토드 2016.2.16 11:19
    • 알겠습니다. 이 사이트가 아직 적응이 안되서 뭐가 어떻게 돌아가는지를 모르겠네요. 알 수 없는 사용자 2016.2.16 11:57
  • TextAsset textAsset = (TextAsset) Resources.Load("Catalog");  
    XmlDocument xmlDoc = new XmlDocument ();
    xmlDoc.LoadXml ( textAsset.text );
    

    이 경로가 접근이 안된다고 하셨는데요. 유니티에서 폴더 구조를 이렇게 만드신게 맞나요? Resource에 있는 모든 파일은 안드로이드로빌드 하더라도 접근이 가능합니다.

    alt text

    • 질문 맨 아랫부분에 사진 추가했습니다.TextAsset textAsset = (TextAsset) Resources.Load("/xml/Catalog"); XmlDocument xmlDoc = new XmlDocument (); xmlDoc.LoadXml ( textAsset.text ); 이 되겠죠. 알 수 없는 사용자 2016.2.16 12:26
  • 방금 제가 올려드렸던 코드 빌드해서 실행해보니 안드로이드에서 잘 동작합니다. Resources에 있는 내용을 TextAsset으로 읽어오는게 왜 안되는지는 잘 모르겠네요. 너무 당연히 되어야 하는 부분이라서요.

    안드로이드 폰에서 돌리면서 로그 찍어본 부분 첨부합니다. Catalog.xml파일에서 Title만 Debug.Log로 찍고 있었는데 곡 이름이 찍히는게 잘 보입니다.

    02-16 13:07:53.387    3637-3652/? D/Unity﹕ RGB GL_EXT_sRGB_write_control GL_EXT_texture_sRGB_decode GL_EXT_texture_filter_anisotropic GL_EXT_multisampled_render_to_texture GL_EXT_color_buffer_float GL_EXT_color_buffer_half_float GL_EXT_disjoint_timer_query
    02-16 13:07:54.357    3637-3652/? I/Unity﹕ Empire Burlesque
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Hide your heart
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Greatest Hits
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Still got the blues
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Eros
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ One night only
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Sylvias Mother
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Maggie May
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Romanza
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ When a man loves a woman
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Black angel
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ 1999 Grammy Nominees
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ For the good times
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Big Willie style
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Tupelo Honey
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Soulsville
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ The very best of
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Stop
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Bridge of Spies
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Private Dancer
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Midt om natten
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Pavarotti Gala Concert
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ The dock of the bay
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Picture book
        (Filename: ./artifacts/generated/common/runtime/UnityEngineDebugBindings.gen.cpp Line: 65)
    02-16 13:07:54.367    3637-3652/? I/Unity﹕ Red
    
    
    
    • xml파일을 txt파일로 바꿔주니 되네요..; 뭔 이유인지.. 답변 감사드립니다. 알 수 없는 사용자 2016.2.16 20:00
    • 혹시 기왕 이렇게 된거 시리얼라이즈 하는 방법도 알 수 있을 까요 ㅡ,ㅡ.. QuestContainer에 있는 리스트 별로 xml에 저장되어야 하는데, 설마 node를 하나씩 만들어서 아예 새로운 xml파일을 만들어야 하는겁니까? iostream을 이용 못하니 여간 불편한게아니네요. 알 수 없는 사용자 2016.2.16 21:14
    • 제 xml 파일에 있는데로 보면, 시작이라는 questname을 가진 노드를 찾아서 하위 노드들을 전부 possible로 옮긴다거나, confrim으로 옮긴다거나 하는기능이 있으면 좋을텐데요. 알 수 없는 사용자 2016.2.16 22:40
    • 스레드가 길어져서 첫번쨰 답변을 수정했습니다. 정토드 2016.2.17 11:33
    • 답변 갑사드립니다. 어디서 구한 정보이신지 혹시 알 수 있으면 좋겠네요. pathForDocumentsFile에 있는 안드로이드 path는 resource인가요 streamingassets인가요? 알 수 없는 사용자 2016.2.17 16:12
    • 정보는 구글링해서 찾아봤어요. 이거저거의 조합이라 딱히 소스가 어딘지를 말씀드리기가 애매하네요. Unity Xml serialize로 검색했어요.안드로이드 파일이 어디 저장되는지는 저도 잘 모르겠네요. 정토드 2016.2.17 16:29

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)